Document Generation
Introduction
Document Generator enables you to generate documents from the information in your application's database.
Documents are generated based on a template that you create. You can create .txt or .html templates.
- A .txt file generates a .txt file from the data retrieved from the database.
- An .html file creates either an .html file from the data retrieved from the database, or, if specified, generates a .pdf file based on an .html file of the data retrieved.
Additionally, you can supply other assets, such as images and style sheets, so you can create professional results.
There is no need to install Document Generator. You simply need to inject it into the module where you are going to use it.
Creating a template and other assets
You must create the template of the information you need and upload it to FILE_STORAGE (see Document Management for more information on uploading/downloading files).
If you need any other assets to produce the results you need (images, css files etc.), you must also upload these to FILE_STORAGE. Along with this, you must create and upload a TEMPLATE_ASSET record that maps these assets to the template.
Using the Document Generator
There are two methods for generating documents:
generateContent
generates the raw content of the file, which is returned alongside any corresponding AssetIds (images, styling or other relevant files that you uploaded with the template). This can be used for generating .txt and .html files, but not .pdf files.generateAndStore
generates a file based on the template provided. The file is uploaded to FILE_STORAGE and the corresponding FileStorageID is returned.
DocumentContentConfiguration
The generateContent
method takes in an object with the following parameters:
templateId
is the FileStorageId for the template you want to generate the document from.userName
is the username of the user generating the document.data
is the map of data to be substituted in the template (the key in the map must match the placeholder in the template file!).deleteOnExit
controls whether to delete the working directory once the result has been produced (default: true).workingDirectory
is the optional path to a working directory (default: a temporary directory is created in the system).
For example:
DocumentContentConfiguration(
templateId = "FILE_0001",
userName = "JohnDoe",
data = mapOf("trades" to Trade(price = BigDecimal.ONE, quantity = 1, counterparty = "counterparty", side = Side.BUY, account = "account")))
DocumentContentResult
The generateContent
method returns an object with the following parameters:
rawContent
is the content of the resulting document generation.assetIds
is a list of corresponding asset ids that are mapped to the provided template.
For example:
DocumentContentResult(
rawContent = "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\">...",
assetIds = listOf("ASSET_001", "ASSET_002")
)
DocumentStorageConfiguration
The generateAndStore
method takes in an object with the following parameters:
- everything in DocumentContentConfiguration.
fileName
is the file name for the document you would like to generate. This must include the file extension of the type of file that you want to generate.
For example:
DocumentStorageConfiguration(
templateId = "FILE_0001",
fileName = "trades-pdf-gen.pdf",
userName = "JohnDoe",
data = mapOf("trades" to Trade(price = BigDecimal.ONE, quantity = 1, counterparty = "counterparty", side = Side.BUY, account = "account")),
deleteOnExit = false,
workingDirectory = "tmp/provided_dir")
DocumentStorageResult
The generateAndStore
method returns an object with the following parameters:
fileStorageId
is the FileStorageId of the generated file.
For example:
DocumentStorageResult(
fileStorageId = "FILE_0002"
)
Template types
HTML templates
When you provide an HTML template, Thymeleaf is used to output the processed text.
Thymeleaf can process complex data objects, so the HTML template can include loops (as shown in the example below). This enables you to provide more than one row of data.
Here is an example of part of an HTML template file:
<tbody>
<tr th:each="trade : ${trades}">
<td th:text="${trade.price}">1.00</td>
<td th:text="${trade.quantity}">1000</td>
<td th:text="${trade.counterparty}">Counterparty1</td>
<td th:text="${trade.side}">BUY</td>
<td th:text="${trade.account}">Account1</td>
</tr>
</tbody>
Users can then provide the trade data that they would like to be displayed, and generate a file.
If the user wants to receive the generated HTML content to send as an email, the data object could be as below, where the key of each object in the map must correspond to a placeholder in the html template.
val trade = Trade(price = BigDecimal.ONE, quantity = 1, counterparty = "counterparty", side = Side.BUY, account = "account")
val data = mapOf("trades" to listOf(trade))
TXT templates
When a TXT template is provided, the TXT template engine uses a simple substitution syntax. Thus, each field must be added individually. The TXT engine automatically gets system definition keys as well as any environment variables as part of its data context.
For example, a TXT template can include the following:
Price: {{PRICE}}
Quantity: {{QUANTITY}}
Counterparty: {{COUNTERPARTY}}
Side: {{SIDE}}
Account: {{ACCOUNT}}
The corresponding data object would be:
val data = mapOf("PRICE" to 1, "QUANTITY" to 5, "COUNTERPARTY" to "counterparty_id", "SIDE" to Side.BUY, "ACCOUNT" to "account_id")
Dependencies
To inject the Document Generator, set up the following dependency in the module where you are going to use it.
Version: 7.1.1
- Gradle
- Maven
implementation("global.genesis:file-server-app:$version")
<dependency>
<groupId>global.genesis</groupId>
<artifactId>file-server-app</artifactId>
<version>$version</version>
</dependency>
Examples
A Document Generator in an Event Handler
This example injects a Document Generator into an Event Handler file. It generates and stores a pdf file (so you must have uploaded a template in HTML format) for use with an email.
val documentGenerator = inject<DocumentGenerator>()
eventHandler<PdfGeneratorData>(name = "GENERATE_PDF_EMAIL") {
onValidate {
ack()
}
onCommit { event ->
val details = event.details
val trade = entityDb.get(Trade.byId(details.tradeId))
val tradeMap : Map<String, Any> = mapOf(
"trades" to listOf(trade)
)
val documentStorageResult =
documentGenerator.generateAndStore(
DocumentStorageConfiguration(
templateId = "FILE_0001",
fileName = "trades-pdf-gen.pdf",
userName = "JohnDoe",
data = tradeMap,
deleteOnExit = false,
workingDirectory = "tmp/provided_dir")
)
// custom code block ...
ack()
}
}
A Document Generator in a module constructor
This example injects Document Generator into a module constructor. It generates content only.
@Module
class GeneratePdf @Inject constructor(
val entityDb: AsyncEntityDb,
private val documentGenerator: DocumentGenerator
) {
val trades = entityDb.getBulk(TRADE).toList()
val tradeMap : Map<String, Any> = mapOf(
"trades" to listOf(trades)
)
val documentContentResult =
documentGenerator.generateContent(
DocumentContentConfiguration(
templateId = "FILE_0001",
userName = "JohnDoe",
data = tradeMap,
deleteOnExit = false,
workingDirectory = "tmp/provided_dir")
)
// custom code block ...
}