Skip to end of metadata
Go to start of metadata

Classes of LINQ Reporting Engine are located within the Aspose.Words.Reporting namespace. The main of the classes is ReportingEngine. All the functionality required to build a report from a template is assembled within the class.

Contents Summary
  

Building Reports

To build a report from a template, you can use one of the ReportingEngine.BuildReport overloads. The following table describes parameters of these overloads.

Parameter

Description

document

A template document. At runtime, this document instance is populated with a data from the specified source and becomes a ready report.

dataSource

An object providing a data to populate the specified template. The object must be of one of the following types:

  • A traditional mail merge data source (see “Working with Traditional Mail Merge Data Sources” for more information)
  • An object of a custom visible type (see “Working with Types” for more
    information)

dataSourceName

The identifier of the specified data source object within the specified template. You can omit this identifier, if the template uses the contextual object member access (see “Using Contextual Object Member Access” for more information) when dealing with the data source.

Given a template to be populated with a data from a DataSet instance that is identified as “ds” within the template, you can use the following code to build the corresponding report.

Given a visible Person class defined in your application and a template to be populated with a data about a single Person instance using the contextual object member access, you can use the following code to build the corresponding report.

Setting up Known External Types

LINQ Reporting Engine must be aware of custom external types that you reference in your template before the engine processes the template. You can set up external types known by the engine through the ReportingEngine.KnownTypes property. The property represents an unordered set (that is, a collection of unique items) of Type objects. Every type in the set must meet requirements declared at “Working with Types”.

Aliases of simple types like int, string, and others are known by the engine by default.

Consider the following example. Given an ImageUtil class declared at your application and a template accessing a static member of this class, you can use the following code to make the engine be aware of the class before processing the template.

Removing Paragraphs Containing Only Template Syntax Tags

While building a report, some paragraphs containing only template syntax tags can become empty after the tags are removed or replaced with empty values. To remove suExample 1ch paragraphs from the report, you can apply the ReportBuildOptions.RemoveEmptyParagraphs option as shown in the following example.

ReportingEngine engine = new ReportingEngine();
engine.Options |= ReportBuildOptions.RemoveEmptyParagraphs;
engine.BuildReport(...);

The difference in the engine’s behavior when the option is applied and not applied is illustrated by the following examples.

Example 1

Template document

Prefix

<<[""]>>

Suffix

Result document without ReportBuildOptions.RemoveEmptyParagraphs applied

Prefix

 

Suffix

Result document with ReportBuildOptions.RemoveEmptyParagraphs applied

Prefix

Suffix

Example 2

Template document

Prefix

<<if [false]>>

Text to be removed

<</if>>

Suffix

Result document without ReportBuildOptions.RemoveEmptyParagraphs applied

Prefix

 

Suffix

Result document with ReportBuildOptions.RemoveEmptyParagraphs applied

Prefix

Suffix

Example 3

Note – In this example, persons is assumed to be a data table having a field Name.

Template document

Prefix

<<foreach [in persons]>>

<<[Name]>>

<</foreach>>

Suffix

Result document without ReportBuildOptions.RemoveEmptyParagraphs applied

Prefix

 

John Doe

 

Jane Doe

 

John Smith

 

Suffix

Result document with ReportBuildOptions.RemoveEmptyParagraphs applied

Prefix

John Doe

Jane Doe

John Smith

Suffix

Accessing Missing Members of Data Objects

By default, LINQ Reporting Engine forbids access to missing members of data objects used to build a report in template expressions, since such access is forbidden by C# Language Specification 5.0. On attempt to use a missing member of a data object, the engine throws an exception then.

But in some scenarios, members of data objects are not exactly known while designing a template. For example, if using a DataSet instance loaded from XML without its schema defined, some of expected data members can be missing.

To support such scenarios, the engine provides an option to treat missing members of data objects as null literals. You can enable the option as shown in the following example.

ReportingEngine engine = new ReportingEngine();
engine.Options |= ReportBuildOptions.AllowMissingMembers;
engine.BuildReport(...);

Consider the following example. Given that r is a DataRow instance that does not have a field Missing, by default, the following template expression causes the engine to throw an exception while building a report.

<<[r.Missing]>>

However, if ReportBuildOptions.AllowMissingMembers is applied, the engine treats access to such a field as a null literal, so no exception is thrown and simply no value is written to the report then.

Inlining Syntax Error Messages into Templates

By default, LINQ Reporting Engine throws an exception when encounters a template syntax error. Such an exception provides information on a reason of the error and specifies a tag or expression part where the error is encountered. In most cases, this information is enough to find a place in a template causing the error and fix it.

However, when dealing with complex templates containing a large number of tags, it becomes harder to find an exact place in a template causing an error. To make things easier, the engine supports the ReportBuildOptions.InlineErrorMessages option that enables inlining of a syntax error message into a template document at an exact position where the error occurs during runtime.

Note – A template syntax error message is written using a bold font to make it more apparent.

Consider the following template.

<<var [name]>>

By default, such a template causes the engine to throw an exception while building a report. However, when ReportBuildOptions.InlineErrorMessages is applied, no exception is thrown and the report looks as follows then.

<<var [name] Error! An assignment operator is expected. >>

Note – Only messages describing errors in template syntax can be inlined; messages describing errors encountered during expressions’ evaluation cannot.

When ReportBuildOptions.InlineErrorMessages is applied, a Boolean value returned by a ReportingEngine.BuildReport overload indicates whether building of a report was finished successfully or was interrupted because of a template syntax error. This enables you to process reports which building succeeded or failed differently as shown in the following code snippet.

ReportingEngine engine = new ReportingEngine();
engine.Options |= ReportBuildOptions.InlineErrorMessages;

if (engine.BuildReport(...))
{
    // Do something with a successfully built report.
}
else
{

    // Do something with a report containing a template syntax error.
}

Note – When ReportBuildOptions.InlineErrorMessages is not applied, ReportingEngine.BuildReport overloads return true if there were no template syntax errors encountered or throw an exception otherwise.

 

Optimizing Reflection Calls

LINQ Reporting Engine uses reflection calls while accessing members of custom external types. However, reflection calls are much slower than direct calls, which create a performance overhead.

That is why, the engine provides a strategy minimizing the reflection usage. The strategy is based upon the runtime type generation. That is, the engine generates a proxy type per an external type. The proxy directly calls members of the corresponding external type, the engine to access these members in a uniform way with no reflection involved. The proxy is lazily initialized and reused in further. Thus, the reflection is used only while building the proxy.

Although this strategy can significantly minimize the reflection usage in a long run, it creates a performance overhead of the runtime type generation. So, if you deal with small data collections all the time while building your reports, consider the disabling of the strategy. You can control the enabling of the strategy through the ReportingEngine.UseReflectionOptimization static property. By default, the strategy is enabled.

Labels
  • No labels