. . .

DocumentGenerator Module

Introduction

The DocumentGenerator takes a Jasper template, fills fields inside that template and generates a document of one of the following types :

  • pdf

  • docx

  • csv

  • txt

  • xls

  • xml

  • rtf

Key Capabilities

Capability

Description

Document generation

The DocumentGenerator module basically converts a Jasper template to a file.

Supports Jasper templates

It is possible to inject values to the Jasper document that should be converted.

Module Setup and Configuration

No configuration needed.

Limitations

  • Only the file types listed above are supported.

  • Fields must be of type String because of the key value Map.

Example

Follow the quick guide steps provided below in order to create the desired document.

Example (Quick Guide)

  1. Create an instance of DocumentTemplate and upload your desired Jasper template.

  2. Create an instance of DocumentSubTemplate, upload your desired Jasper (sub-)template and reference it on your previously created instance of DocumentTemplate (optional).

  3. Create as many instances of DataSource as you need for all fields that occurs in your Jasper template. The placeholders of these fields will get resolved within the template by $F{template_field_key}.

  4. Create a Document object and set references to your template and your datasources, as well as the desired file type and name for the generated file.

  5. When you finished giving the required information to the Document, set "generate" to 1. Now, the module will create the Document. It should be available for download after a short moment.

Example (Detailed Guide)

First of all, make sure the DocumentGenerator module is attached to your Backend app (see My Modules) so your ApiOmat instance looks like this :

images/download/attachments/63116874/1.png

1. Create Jasper Template

Simply go to the dashboard data editor, select the class DocumentTemplate, create a new instance and upload your Jasper template file into the attribute "mainTemplateFile".

Attention: Jasper templates are created in JRXML and have to be compiled to Jasper in order to work with the DocumentGenerator module.

Sample JRXML template
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.6.0.final using JasperReports Library version 6.6.0 -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="template_Table" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" resourceBundle="test_resource" uuid="e18e1ce6-d1fd-4ec2-958a-7c91e402f9b6">
<style name="Table_TH" mode="Opaque" backcolor="#F0F8FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="Table_CH" mode="Opaque" backcolor="#BFE1FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<subDataset name="Dataset" uuid="dc2bdc3d-4c1c-4d08-b51c-615d6c78a8f0">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="name" class="java.lang.String"/>
<field name="species" class="java.lang.String"/>
<field name="age" class="java.lang.String"/>
</subDataset>
<parameter name="TableDataSource" class="net.sf.jasperreports.engine.data.JRMapCollectionDataSource"/>
<parameter name="subDataSource" class="net.sf.jasperreports.engine.data.JRMapCollectionDataSource"/>
<parameter name="subTemplateTable" class="java.io.InputStream"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="date" class="java.lang.String"/>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="120" splitType="Stretch">
<textField>
<reportElement x="152" y="0" width="250" height="83" uuid="c43fac32-085f-4a35-842b-4f90e52bbc62"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font size="33"/>
</textElement>
<textFieldExpression><![CDATA[$R{titel}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="227" y="70" width="100" height="30" uuid="a17e32d6-ca21-4f14-a98c-bfa053ef7b31"/>
<textElement textAlignment="Center">
<font size="14"/>
</textElement>
<textFieldExpression><![CDATA[$F{date}]]></textFieldExpression>
</textField>
</band>
</title>
<pageHeader>
<band height="35" splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band height="70" splitType="Stretch">
<componentElement>
<reportElement x="27" y="-20" width="500" height="90" uuid="c6e73d1b-02b4-4bf5-a59b-0dcc84d3006f">
<property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
<property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/>
<property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/>
<property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/>
</reportElement>
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<datasetRun subDataset="Dataset" uuid="2a02a6c4-a638-4a5a-8085-787bde9725d8">
<dataSourceExpression><![CDATA[$P{TableDataSource}]]></dataSourceExpression>
</datasetRun>
<jr:columnGroup width="500" uuid="be3057b8-7c70-4adb-af38-961cc6eeeb2a">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Columns [3]"/>
<jr:tableHeader style="Table_TH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="500" height="30" uuid="fb817c07-8b34-4aeb-aff3-d9a961cee8b5"/>
<textElement textAlignment="Center" verticalAlignment="Bottom">
<font size="22"/>
</textElement>
<text><![CDATA[Zoo Table]]></text>
</staticText>
</jr:tableHeader>
<jr:column width="167" uuid="1034277b-9870-4198-8f95-3bd5768094f8">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="167" height="30" uuid="22fcb14c-61b8-4ec9-9e4a-a8e7476caeb8"/>
<textElement textAlignment="Center" verticalAlignment="Bottom">
<font size="16"/>
</textElement>
<text><![CDATA[species]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="167" height="30" uuid="4c26df6b-0a1f-4403-a37e-39fadf0e4df9"/>
<textFieldExpression><![CDATA[$F{species}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="167" uuid="5265b812-202c-4c69-8550-de1ab093a2d0">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column2"/>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="167" height="30" uuid="a7f7ba4b-c7ff-4c04-b64a-822711aedc61"/>
<textElement textAlignment="Center" verticalAlignment="Bottom">
<font size="16"/>
</textElement>
<text><![CDATA[name]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="167" height="30" uuid="873ac9c1-d1e0-43e1-9d5c-e8a20f3098e7"/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="166" uuid="8f74a74d-5838-4bbd-96c0-f0bd9ff13e0c">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column3"/>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="166" height="30" uuid="759896d5-c8d4-4f6e-82ae-4a5921fc7fda"/>
<textElement textAlignment="Center" verticalAlignment="Bottom">
<font size="16"/>
</textElement>
<text><![CDATA[age]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="166" height="30" uuid="09b55faa-f2cb-4c61-ba62-a67f672028ca"/>
<textFieldExpression><![CDATA[$F{age}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:columnGroup>
</jr:table>
</componentElement>
</band>
</columnHeader>
<detail>
<band height="298" splitType="Stretch">
<subreport>
<reportElement x="27" y="10" width="500" height="200" uuid="3e957a5c-efa5-4941-966c-eb312acbae79"/>
<dataSourceExpression><![CDATA[$P{subDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA[$P{subTemplateTable}]]></subreportExpression>
</subreport>
</band>
</detail>
</jasperReport>

Your DocumentTemplate instance should now look like this :

images/download/attachments/63116874/2.png

After posting the file the dataSetKeys and dataSourceNames are generated automatically from the template file.

DataSetKeys show keys of fields and dataSourceNames names of parameters in the template.

2. Create a SubTemplate (optional)

Next, select the class DocumentSubTemplate, create a new instance and upload your Jasper (sub-)template into the attribute "subTemplateFile".

Sample JRXML template
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.6.0.final using JasperReports Library version 6.6.0 -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="subTemplateTable" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="a5e289a6-1239-4ed6-a770-90d2a116467c">
<subDataset name="Dataset" uuid="3e285e0b-5395-401f-86a0-3be889df6e58">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<parameter name="Parameter1" class="java.lang.String"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="pfleger" class="java.lang.String"/>
</subDataset>
<parameter name="subDataSource" class="net.sf.jasperreports.engine.data.JRMapCollectionDataSource"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="pflegers" class="java.util.List"/>
<field name="pflegeDate" class="java.lang.String"/>
<background>
<band splitType="Stretch"/>
</background>
<detail>
<band height="108" splitType="Stretch">
<componentElement>
<reportElement x="10" y="34" width="529" height="62" uuid="76d25ae9-3ef5-4bc6-9242-c1eb9828ec8a"/>
<jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
<datasetRun subDataset="Dataset" uuid="d126a1c1-d7f0-42b1-aa99-78feab753ee9">
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data. JRMapCollectionDataSource($F{pflegers})]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="62" width="529">
<textField>
<reportElement x="170" y="13" width="215" height="30" uuid="882683ec-b10a-4dfb-a589-21593a7253b7"/>
<textFieldExpression><![CDATA[$F{pfleger}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
<textField>
<reportElement x="10" y="8" width="100" height="20" uuid="4633e4eb-e6ce-417a-9c48-7467d13fb38b"/>
<textFieldExpression><![CDATA[$F{pflegeDate}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>

The DocumentSubTemplate instance should now look like this :

images/download/attachments/63116874/3.png

To use your created instance of DocumentSubTemplate, reference it on the "subTemplates" attribute of your DocumentTemplate, so it looks something like this:

images/download/attachments/63116874/4.png

After referencing the DocumentSubTemplate object to the DocumentTemplate object the dataSetKeys and the dataSourceNames attributes get extended by the field and parameter names of the subTemplate file.

3. Create Template DataSources

Now, the empty fields in the templates need their referring datasources.

DataSources can be a "dataSource" or part of the "subDataSources" in the Document object.

The differences between dataSources and subDataSources are the following:

  • every template has exactly one dataSource, but can have many subDataSources

  • dataSources fill fields in the template that aren't in any sub dataset (i.e. tables or sub-templates)

  • subDataSources are connected to their sub dataset via dataSourceName

If you are uncertain which keys or dataSourceNames are allowed, you can look them up in your previously created instance of Template under dataSetKeys and dataSourceNames.

The attribute OrdNr allows you to set the order for datasources. If the OrdNr of a datasources isn't set, it's simply added at the end.

If you need to link multiple datasources with equal keys to a superior dataSource, you can do that via the "refDataSources" and the "refDataSourceName" attributes, simply add a "refDataSourceName" to your lower datasources and reference them on the "refDataSources" attribute of your higher datasource.

In this example, two "subDataSources" (one with & one without a refDataSource) and a "dataSource" for our Document object are created.

Open your data editor and select the class DataSource in the navigation bar.

Create a new instance and fill in the values from the following table in the attributes :

Example for "subDataSources" with refDataSources:

Class

dataSet

dataSourceName

ordNr

refDataSources

DocumentGenerator.DataSource

pflegeDate : 01.01.01

subDataSource

reference to refDataSource

Example for refDataSource:

Class

dataSet

refDataSourceName

ordNr

DocumentGenerator.DataSource

pfleger : susi

pflegers

Example for "subDataSources" without refDataSources:

Class

dataSet

dataSourceName

ordNr

DocumentGenerator.DataSource

species : polar bear

TableDataSource

1

name : lennard

age : 7

Example for a/the "dataSource":

Class

dataSet

dataSourceName

ordNr

DocumentGenerator.DataSource

date : 01.02.03

(doesn't matter)

(doesn't matter)

Your instance of DataSource should now look like this:

images/download/attachments/63116874/5.png

4. Generate Document

After the Document(Sub)Template and the DataSources are complete it is time to generate the document :

  • Open the data editor and select the class Document.

  • Fill the class attribute template by selecting the reference to the created DocumentTemplate of the first step.

  • Now you can add the "dataSource" and the "subDataSources" you created. If you are using refDataSources, just link the higher dataSource (the lower ones will be added automatically).

  • Set a name for your generated file in attribute "name" and select the file type (pdf, docx, csv, txt, xls, xml or rtf) which will be generate under "fileType" attribute.

  • There is also the possibility to nationalize the Document in two different ways:

  1. the "language" attribute
    Just give this this attribute an official country code like "en" and location specific formats will be adopted automaticall (e.g. for dates).

  2. the "langProperties" attribute
    To use this attribute, your template file has to contain a resource bundle and fields with the right syntax to be filled with different values depending on the nationalization.
    Post a file with the following structure: <filename>_<country code>.properties.
    There can only be one properties file per Document object.
    If the "langProperties" attribute is set, the cobntent of the "language" attribute does not matter anymore.
    Attention: if the jasper template requires a properties file, the properties file must be uploaded first.

  • After setting these attributes, set "generate" value to 1 and the module will generate the document automatically. The generated document will be stored in the attribute "resultFile", ready to be downloaded.

images/download/attachments/63116874/6.png

images/download/attachments/63116874/7.png

Generate Document resultFile via native module code

The generation of a document can also be executed by creating the needed class instances from above via native module code :

generating file via nativemodule
r.setHooksInUsedModulesEnabled( true );
try (
InputStream subTempData = getClass( ).getClassLoader( ).getResourceAsStream( "src/META-INF/imports/subTemplateTable.jasper" );
InputStream tempData = getClass( ).getClassLoader( ).getResourceAsStream( "src/META-INF/imports/template_Table.jasper" );
InputStream propData = getClass( ).getClassLoader( ) .getResourceAsStream( "src/META-INF/imports/test_resource_de.properties" );
)
{
 
final DocumentSubTemplate subTemp = this.model.createObject( DocumentSubTemplate.class, r );
subTemp.save( );
subTemp.postSubTemplateFile( subTempData, "subTemplateTable", "jasper" );
subTemp.save( );
 
final DocumentTemplate temp = this.model.createObject( DocumentTemplate.class, r );
temp.save( );
temp.postMainTemplateFile( tempData, "template_Table", "jasper" );
temp.save( );
temp.postSubTemplates( subTemp );
temp.save( );
 
final DataSource subDataSource = this.model.createObject( DataSource.class, r );
Map map = new HashMap<>( );
map.put( "name", "lennard" );
map.put( "species", "polar bear" );
map.put( "age", "7" );
subDataSource.setDataSet( map );
subDataSource.setDataSourceName( "TableDataSource" );
subDataSource.setOrdNr( 1L );
subDataSource.save( );
 
final DataSource dataSource = this.model.createObject( DataSource.class, r );
map = new HashMap<>( );
map.put( "date", "01.02.03" );
dataSource.setDataSet( map );
dataSource.save( );
 
final Document document = this.model.createObject( Document.class, r );
document.save( );
document.postLangProperties( propData, "test_resource_de", "properties" );
document.save( );
document.postTemplate( temp );
document.postSubDataSources( subDataSource );
document.postDataSource( dataSource );
document.setName( "Test" );
document.setFileType( "pdf" );
document.setGenerate( 1L );
document.save( );
}

Generate Document resultFile via SDK

The generation of a document can also be executed by creating the needed class instances from above via a SDK of your choice. In the following example the Java SDK is used.

generating file via SDK
DocumentTemplate template = new DocumentTemplate( );
byte[ ] data = getResourceFileAsBytes( "imports/template_Table.jasper" );
template.postMainTemplateFile( data, "template_Table", "jasper" );
 
DocumentSubTemplate subTemplate = new DocumentSubTemplate( );
final byte[ ] subData = getResourceFileAsBytes( "imports/subTemplateTable.jasper" );
subTemplate.postSubTemplateFile( subData, "subTemplateTable.jasper", "jasper" );
 
template.postSubTemplates( subTemplate );
template.load( );
 
DataSource mainDataSource = createDataSource( );
Map<String, String> map = new HashMap<>( );
map.put( "pflegeDate", "01.01.01" );
mainDataSource.setDataSet( map );
mainDataSource.setDataSourceName( "subDataSource" );
mainDataSource.save( );
 
DataSource refDataSource = createDataSource( );
map = new HashMap<>( );
map.put( "pfleger", "susi" );
refDataSource.setDataSet( map );
refDataSource.setRefDataSourceName( "pflegers" );
refDataSource.save( );
 
mainDataSource.postRefDataSources( refDataSource );
 
DataSource subDataSource = createDataSource( );
map = new HashMap<>( );
map.put( "species", "polar bear" );
map.put( "name", "lennard" );
map.put( "age", "7" );
subDataSource.setDataSet( map );
subDataSource.setDataSourceName( "TableDataSource" );
subDataSource.setordNr( 1L );
subDataSource.save( );
 
DataSource dataSource = createDataSource( );
Map<String, String> map = new HashMap<>( );
map.put( "date", "01.02.03" );
dataSource.setDataSet( map );
dataSource.save( );
 
Document document = new Document( );
final byte[ ] propData = getResourceFileAsBytes( "imports/test_resource_de.properties" );
document.postLangProperties( propData, "test_resource_de", "properties" );
document.postTemplate( template );
document.postSubDataSources( mainDataSource );
document.postSubDataSources( subDataSource );
document.postDataSource( dataSource );
document.setName( "Test" );
document.setFileType( "pdf" );
document.setGenerate(1L);

Module Classes Overview

The following table contains information about the DocumentGenerator classes, their attributes and their meaning :

Class Name

Class Description

Class Attribute

Class Attribute Description

DataSource

class for datasources that will be written to fields of the template

dataSourceName

a string that refers to the name of a parameter in the template and is used to funnel datasources to sub datasets

dataSet

a list of maps (keys refer to fields in the template where the values are inserted)

ordNr

an integer, which defines the position of a dataSource

refDataSourceName

a string that refers to the name of a special field in the template, which is used to contain multiple datasources with equal keys

refDataSources

a reference to DataSource used to link lower datasources to a higher one

DocumentTemplate

an object of this class takes a Jasper template and
generates all fields & dataSources into lists of strings

mainTemplateFile

file to place the Jasper template in

dataSourceNames

list of all string parameters from the template

dataSetKeys

list of all string fields from the template

DocumentSubTemplate

an object of this class contains a Jasper template, which can be linked to an instance of DocumentTemplate

subTemplateFile

file to place the jasper (sub-)template in

subTemplates

a reference to DocumentSubTemplate(s) of the template

Document

an object of this class uses a template, datasources and specifications to create a document from Jasper.

name

a String that is going to be the name of the generated document

template

a reference to DocumentTemplate used to render the desired document

resultFile

this place is filled by the resulting document if it can successfully be created

subDataSources

a reference to DataSource used to fill fields in a parameter of the template

dataSource

a reference to a DataSource used to fill fields (that aren't in a parameter) of the template

fileType

a String that is going to be the file type if the generated document (must be pdf, docx, csv, txt, xls, xml or rtf)

generate

a long that defines whether the resultFile should be generated (set generate to 1) or not (set generate to any other long or nothing)

langProperties

a file with the ending .properties which makes it possible to specify country related (static) Strings for a field in the template

language

a string that is an official country code (for country related formatting)