GroupDocs.Assembly Cloud is a powerful web-based Document Automation and Report Generation solution, designed to generate data-bound documents through templates dynamically.
The main Report Generation concept, presented on the image below, is simple and consistent:
Document Templates
A document template is just a normal document, created with Microsoft Office, OpenOffice or any other compatible office suite (LibreOffice, WPS Office, Polaris Office, Open365, SoftMaker FreeOffice, etc.), that contains special tags for the dynamic content. You are supposed to use that template to assemble documents on this model repeatedly and consistently.
Have a note, that supported template types are not limited to word-processing document templates only, but also include spreadsheet templates, presentation templates, HTML document templates, email document templates, plain-text templates and others.
Data Sources
A Data Source lets you define which data set will be used to bind with a document template and subsequently evaluated in the output.
You can use both JSON and XML files for this purpose. Both formats are hierarchical, self-describing and human-readable. However, JSON may have slight built-in advantages, because it is more compact and thus it is quicker to read and write.
You can use the following simple data types in your JSON and XML files:
Data Type
Description
XML Example
JSON Example
Int32
A 32-bit signed integer
<Age>30</Age>
{"Age": "30"}
Int64
A 64-bit signed integer
<Amount>5612456179438</Amount>
{"Amount": "5612456179438"}
Double
A double-precision floating-point number
<Price>253.9</Price>
{"Price": "253.9"}
Boolean
A boolean value (True or False)
<IsChecked>True</IsChecked>
{"IsChecked": "True"}
DateTime
An instant in time
<OrderDate>2019-10-01T00:00:00</OrderDate>
{"OrderDate": "2019-10-01T00:00:00"}
String
A sequence of Unicode characters
<Name>John Doe</Name>
{"Name": "John Doe"}
Tags and Expressions
Tags and Expressions are the fundamental elements of the report generation technique, that are located in the document template and intended for the purposes of dynamic content management. At its simplest, a tag defines a command for the Reporting Engine, and the expression, which is an integral part of the tag, defines command’s parameters.
In terms of the Reporting Engine, it does not matter what type of document templates you are working with — regardless of the document template type, tags and expression syntax remains the same anywhere. However, you need to use character escaping when working with HTML templates.
A tag is surrounded with a pair of “<<”, “>>” character sequences and consists of the following elements: name, expression, switches and comment:
Some tags require a corresponding closing tag. A closing tag must match the name of the opening tag with the “/” character preceding its name:
<</tagName>>
Depending on the functional role, the following types of tags can be distinguished:
Tag Type
Functional Role
Tags
Tags Description
Control Tags
Provides flow and conditional processing control
foreach, next
Provides flow control for traversing elements of a certain type in a sequence
if, else, elseif
Provides conditional processing control
Content Tags
Used to generate and insert different content elements into the output dynamically
backColor
Defines a background-color for a text
barcode
Inserts a barcode image
check
Sets a checkbox value
link
Inserts a hyperlink
restartNum
Restarts a numbering inside a list
var
Declares a variable
Chart Tags
Used to populate charts with data
pointColor
Defines a color for a chart series
removeif
Removes a chart series, depending on the condition
seriesColor
Defines a color of a chart series
size
Defines a bubble size for a bubble chart
x, y
Specifies a data mapping for chart coordinates
Expressions are the most interesting part of a tag syntax. They are composed of operands, usually presented in the form of Data Field references, and Operators, defined according to the “C# Language Specification 5.0”.
Data Bands
A Data Band is a template for sequential data processing. During the document generation process, the Reporting Engine connects each data band to a data source using Data Field references and processes it as many times as there are records in the data source. As a result, the data band body is replicated and appended to the output document.
Data Band Syntax
A data band is made up of two parts:
A pair of opening and closing foreach loop tags, that represent the scope of a control flow statement for traversing elements in a sequence. Depending upon the developer’s objectives the foreach tag syntax may vary.
A Data Band Body, defined between the foreach pair of tags, which represents a template for a single element of a sequence. A data band body may contain nested data bands.
The complete syntax of a data band is provided below:
An iteration variable, defined by name and type, is intended to reference an element of a sequence inside a data band body.
Variable’s name and type are optional parameters, that can be specified or omitted depending on the aspects described in the following table:
Parameter
Use Aspects
Variable Type
If you specify the variable's type explicitly, it must be known by the Reporting Engine.
If you omit the variable's data type, it is determined implicitly depending on the type of the corresponding element sequence.
Variable Name
If you specify the variable's name, it must be unique within the scope of the corresponding foreach tag.
If you omit the variable's name, you can still access the variable’s members using the Contextual Field Access syntax.
Data Band Types
When a data band is related to a list, it is called a Common Data Band.
When a data band is related to a table, that is to a single or multiple rows of a table, it is called a Table-Row Data Band.
Depending on the objectives, this type of data band may occupy a different number of table rows. In the simplest cases, it occupies a single row, but in more complicated scenarios, that imply generation of hierarchical tabular data structures, using multirow data bands may be required.
Referencing Fields in a Data Source
To reference a field inside a data source you must provide a string representation of it.
A field reference syntax is straightforward:
<<[field_reference]>>
To make this baseline technique clear, let’s have a look at the sample data sources in XML and JSON and the corresponding data band.
The following XML and JSON data sources represent a list of persons, described by their names and ages.
The corresponding table-row data band is shown below. As you can see, it is referencing the Name and Age fields inside the ds data source, and intended to output the sequence of Person elements to a tabular format in three columns:
Number
Name
Age
<<foreach [p in ds.Persons]>><<[p.NumberOf()]>>
<<[p.Name]>>
<<[p.Age]>><</foreach>>
Count
<<[ds.Persons.Count()]>>
When the report generation process is complete, you’ll see the following output:
Number
Name
Age
1
John Doe
30
2
Jane Doe
27
3
John Smith
51
Count
3
You can also use the Contextual Field Access technique, which enables you to access fields of a data source depending on the processing context. An object, to which the Contextual Field Access can be applied, is determined by the following rules:
Inside a data band body, the object is resolved to the iteration variable.
Outside a data band body, the object is resolved to a passed data source.
The main syntax differences between the standard and the contextual types of field access are submitted in the following table:
Type of Field Access
Iteration Loop Syntax
Field Access Syntax
Standard
<<foreach [variable in sequence]>>
<<[variable.Field]>>
Contextual
<<foreach [in sequence]>>
<<[Field]>>
The complete table-row data band example, that demonstates the Contextual Field Access technique, is provided below:
Number
Name
Age
<<foreach [in Persons]>><<[NumberOf()]>>
<<[Name]>>
<<[Age]>><</foreach>>
Count
<<[Persons.Count()]>>
Managing Paragraph Breaks
While building a report, paragraph breaks derive attributes from their template prototypes. In particular, this fact enables you to build numbered or bulleted lists in reports dynamically.
The following table illustrates some common use-cases with a “¶” symbol, that represents a non-printing control character of a paragraph break.
Given an enumeration of strings ["item1", "item2", "item3"] and a common data band in the left column of the following table, you will get the output, shown in the right column:
You can instruct the Reporting Engine to force movement to the next iteration within a data band using the next tag. This feature is useful in scenarios when you need to output data of a fixed number of elements in a single row.
In the following example, given an enumeration of Person data elements, you can output their names in a row using the following table-row data band:
Name A
Name B
Name C
<<foreach [p in Persons]>><<[p.Name]>>
<<next>><<[p.Name]>>
<<next>><<[p.Name]>><</foreach>>
The result would be as follows:
Name A
Name B
Name C
John Doe
Jane Doe
John Smith
Multi-Row Data Bands
The main purpose of a table-row data band, spread over multiple rows, is to generate nested data structures, for example, in-table lists. The body of this data band starts at the beginning of the first occupied row and ends at the end of the last occupied row as follows:
<<foreach>> …
...
...
...
...
...
… <</foreach>>
The next example demonstrates this advanced technique and shows how to populate a Manager/Client table with a nested in-table Contracts list. Note that the first (outer) data band, that is responsible for iterating and dealing with Manager data elements, occupies two table rows:
Manager / Client
Contract Price
<<foreach [m in ds.Managers]>><<[m.Name]>>
<<foreach [m in ds.Managers]>><<[m.Name]>>
<<foreach [m in ds.Managers]>><<[m.Name]>>
<<[c.Price]>><</foreach>><</foreach>>
Count
<<[ds.Contracts.Sum(c => c.Price)]>>
Conditional Data Processing
A Conditional Block represents a set of template options, bound to associated conditional expressions. During the process of Report Generation, these conditional expressions are sequentially evaluated until an expression that returns True is reached. In this case, the conditional block is replaced with the corresponding template option and populated with data.
A conditional block can have a default template <<else>> option that is not bound with a conditional expression. This template option is used when none of the conditional expressions return True.
You can use the following syntax to declare a conditional block:
The following example shows how you can use conditional expressions to represent a number of elements in a sequence, handling the situation when the sequence is empty:
A template option of a conditional block can be composed of multiple paragraphs and data bands.
For example, given an enumeration of strings ["item1", "item2", "item3"], you can tentatively check whether the enumeration contains any elements before sending them to output:
Given the previous declaration of string items, you can use the following template to apply different formatting for even and odd elements of the sequence:
<<foreach [item in items]>><<if [IndexOf() % 2 == 1]>><<[item]>><<else>><<[item]>><</if>><</foreach>>
In this case, the engine produces a report as follows:
item1item2item3
By analogy with table-row data bands, when a conditional block is related to a table, that is to a single or multiple rows of a table, it is called a Table-Row Conditional Block.
Depending on the objectives, this conditional block may occupy a different number of table rows. In the simplest cases, it occupies a single row, but in many cases it occupies multiple rows of a table.
The body of a table-row conditional block, spread over multiple rows, as well as the body of its every template option, starts at the beginning of the first occupied row and ends at the end of the last occupied row as shown below: