Skip to main content

SAMO-docx Engine (*.pdf)

Header

Level: Jedi Knight/Jedi Master

Keywords: templates, generating pdf files, samo-docx engine

The result: Possibility to create template in *.docx format and generate *.pdf file filled with enity attributes

Using the Template Engine we can generate a pdf file containing the entity attributes into a predefined template in a docx file.

To generate it, we use the scripting API to set the necessary inputs to create the pdf file. This file is created as an attachment to a specific entity instance, which needs to be accounted for in the API method settings.

JS API configuration example
api.features().attachments()
.prepareCreateAttachmentFromTemplateResult(context)
.entityRef(WO) //Reference the entity to which we will "pin" the attachment. In addition to entityRef(), we can also use entityId() and entityType().
.templateEngine("samo-docx") //The name of the templating engine we will use to generate it. Currently, we are using **samo-docx**.
.templateId("bs/protocols/types/templateA.docx") //Path to template file
.fileName("final_protocol") //Name of the generated file
.attachmentType("att_boDocument") //Type of attachment defined in WO entity
.output("pdf")
.model(inputModel) // Model with defined attributes for final protocol
.create();

If you want to study more about generating attachment go to Scrpting API new attachment

But first, we have to prepare data for object inputModel.

Preparing data in JavaScript​

Before generating the pdf report, it is necessary to prepare all the data that we want to be included in the final document.

Use the scripting API to retrieve all the entities that will be passed to the inputModel object.

For example, let's load a Work Order. The final object will look approximately like this:

Work Order Object
{
"id" : 101,
"createDate" : 1628165269000,
"createdBy" : {
"id" : 1,
"username" : "JOSS.WHEDON",
"firstName" : Joss,
"lastName" : "Whedon"
},
"at_workOrder_name" : "Replacement of auxiliary device",
"at_workOrder_code" : "WO2300658501",
"at_workOrder_note" : "It is important to do this task ASAP.",
"at_workOrder_warrantyClaims" : {
"ca_yesNo_description" : "No",
"ca_yesNo_id" : 0
},
"at_workOrder_fr_customer" : {
"id" : 8,
"at_customer_name" : "Nathan Fillion",
"at_customer_address" : "Hollywood 123, USA"
},
"at_workOrder_fr_worker": {
"id" : 42,
"at_worker_name" : "Arthur Dent",
"at_customer_qualification" : "The Engineer"
}
}

This object is stored in the workOrder variable, which contains the structure shown above.

Let's also load the Log entity. For this example, we'll use a simpler structure:

Protocol Object
{
"id" : 101,
"createDate" : 1628165269000,
"createdBy" : {
"id" : 1,
"username" : "ARTHUR.DENT",
"firstName" : "Arthur",
"lastName" : "Dent"
},
"at_protocol_name" : "Replacement of device",
"at_protocol_code" : "AUX",
"at_protocol_note" : "Replaced without problems.",
"at_protocol_success" : {
"ca_yesNo_description" : "Yes",
"ca_yesNo_id" : 1
},
"at_protocol_realizDate" : 1690243200000,
"at_protocol_durationInMinutes" : 90,
"at_protocol_signature": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABgCAYAAABFRcHDAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAALqSURBVHic7Zq9TjJBFIbfNQQp0NASEkoCHcUWbrgCSgoTCwpCg4SGkFAQKTQCiQQwROONyC0oFCSWunZegnELgsV8xWdWV/5s5swkc55q5gzhPe+ePbM/YAkhBAxkT3UCqmDjpsHGTYONmwYbNw02bhps3DTYuGmwcdNg46qxLItUTxvjg8GAVlBoxng8JtGxhOC3rMrY2/ufxsvLix97e3uTqyn12/9Ir9fD/f090um0HyuVSlI1tTnVc7kcHh4e/LllWZCZmhYVB4DHx8fAPJ/PS9VTbvz4+BgAEIvFAnHHcaTqKjcej8cBAP1+PxA/ODiQK0xy0dzBdDpdiY1GI6mayisOAEdHRysxz/Okaio13mw2N649PT3JFZd6Pu0gmUyKi4uLtWuJREKqdkjuYd3OtruzSqUiVVuLG5jFYoFIJBKIeZ6HaDQqTVNZj7daLX98dXW1si7TNAB1Pb6/vy/a7bYQQohwOEyur6zHF4uFPy4UCuT6WvT4fD6Hbdukmkp6/PT0NDCnNg0oqrjsR86/oKTiQgjU6/WN66+vr9Jz0KLHf5PJZPD8/CxVg7zixWJx52dOTk6k50FecR36G1BQcdd1qSXXQm48lUoF5pPJhDoFAMTGz8/PAQDdbtePXV9fU6bwDeX98Tq529vbwLzT6ZDkQlrxcrm8EqvVaoF5NpslyUXL6zgFWrxsVAGZ8V0//F9eXhJl8gXJTiK+NzbXdTeuD4dDqnToNre7uzsA6zc4APj4+KB9PCU7xF9Uq1V/fHNzQy3vQ1Lx9/d3f3x2duaPQyF1b7dJLmfhcBjL5XLj+mw2g23bpAeCpOKfn59b1x3HQaPRoEjlG4p+2iVTLpcp0ghAcqrr8gz+Ey3u3Kj/1QgoNP7zJ2IVZwOJ8XXGDg8PKaQ3wk9npsHGKVGxi/+G3Lgu13Ry4zqYBrjHzYONmwYbNw02bhps3DTYuGmwcdNg46bBxk2DjZsGGzcNNm4abNw0/gEkFT8jtc0/8wAAAABJRU5ErkJggg=="
}

If there are no specific data requirements, we can simply pass these two variables to the model.

Transfer of the model without modifications
var inputModel = {
workOrder: workOrder,
protocol: protocol
}

But one adjustment to the data is necessary. When we look at the protocol, we see that instead of a date, we get a value in a timestamp. So we'll have to modify these values to write the correct date format to the log and not the timestamp.

Transfer of the model with new date format
var protocolDate = api.format().dateTime(context) //This variable now contains a string that stores the date in the format dd.MM.yyyy.
.formatString("dd.MM.yyyy")
.timestamp(protocol.at_protocol_realizDate)
.getFormattedString();

var inputModel = {
workOrder: workOrder,
protocolDate: protocolDate,
protocol: protocol
}

We have the data in the scripting API ready. It's time to prepare the template.

How to prepare template in *.docx file​

First of all, we need to set up Word to show us the developer tools.

In the top bar, click on File and select Options from the left menu.

In the new window, we move to Customize Ribbon section in the left menu. We now have a split window in front of us. On the right-hand side, we need to find the Developer item, which we check and press Ok.

Ribbon setup

Fig. 1: How to show Developer tools

The design of the protocol is entirely up to you. The Samo-docx engine can handle both images and tables.

Let's show how to insert data into this template so that the engine knows where to insert the correct values.

In Word, in the developer tools, click on Rich Text Content Control. This will create the object that is now in the document.

Ribbon setup

Fig. 2: Create RTCC

The next step is to click Properties, which will open a new window.

Ribbon setup

Fig. 3: Where open properties

Here we fill the Tittle and Tag items with the eval value.

Ribbon setup

Fig. 4: Values for TITTLE and TAG

Now I have prepared an object into which we will insert the variable names as we have defined in the model. The entry must enclose the variable name in round brackets ending with an exclamation mark.

This is what the template looks like in Word: Ribbon setup

Fig. 5: DOCX file with variables as template

Result of *.pdf file generation: Ribbon setup

Fig. 6: PDF file with values

Where to find/create templates for generating templates folder:

lids-as
│
└───business-service
│
└───templates
│
└───documents\protocols\types
│
└───templateA.docx

Other useful templating tips​

Design Mode must be activated for the correct and accurate display of the mentioned patterns. Function example

Fig. 7: How to show Design Mode

This is what the template looks like in Word in Design Mode: Function example

Fig. 8: DOCX file with variables as template in Design Mode

Writing template marks​

Tags can be written in two different ways.

Odd marks Function example

Fig. 9: Example of eval function with odd marks

Pair marks Function example

Fig. 10: Example of eval function with pair marks

The difference is that incomplete tags do not create a new paragraph.

Some functions can only use one way of writing tags.

There can be many variants of invalid notation, so if the generation is not working correctly, it is a good idea to check if there is an error in this way of noting the mark.

warning

As for the eval function, only the variant with odd marks is a valid entry, the variant with even marks is not valid.

Forcing a non-existent reference to be written​

If the reference is enclosed in brackets ( )! the function will not require its existence. In case the reference does not exist in the data model, the template will be generated successfully and no error will occur.

tip

Always write referencies with ( )!, this is especially important for beginners. The downside is that if you make a mistake, you may not notice it right away, especially if the template is large. The placeholder will simply be empty after generating the report.

Example of non-existent reference with ( )!: Function example

Fig. 11: Example of non-existent reference with ( )!

Result: the report will be generated and instead of this placeholder there will be only an empty space.

Example of non-existent reference without ( )!: Function example

Fig. 12: Example of non-existent reference without ( )!

Result: the template is not generated and ends with an error message.

Inserting an image​

Use the image function to insert an image. As in the case of the eval function, the image function is only valid in the odd-marked variant. Function example

Fig. 13: Example of image reference

The input data from the data model must be in Base64 format, including the header.

example of an image in Base64 format
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...

A fixed image width can also be set: Function example

Fig. 14: Example of image reference with fixed image width

or one can explicitly set the full width of the image: Function example

Fig. 15: Example of image reference with full image width

Functions overview​

If you want to try the following examples practically, use the model below in the script and omit all the test. prefixes from the placeholders in the functions of the examples in the Word template.

test model example
var model = {
"attributeString": "Example string",
"attributeString1": "Another example string",
"attributeString2": {
"value": 1
},
"attributeNum": 12,
"attributeNum1": 3,
"objectsArray": [
{
"objectAttributeNum": 55,
"objectAttributeString": "Example of a string in an object array"
},
{
"objectAttributeNum": 1221,
"objectAttributeString": "Example of a string1 in an object array"
},
{
"objectAttributeNum": 76,
"objectAttributeString": "Example of a string2 in an object array"
}
],
"html": "<html><p>This is an example of HTML</p></html>"
};

Eval​

Valid notation: odd marks

Invalid notation: pair marks

Examples: Function example

Fig. 16: Examples of simple use of eval function

Strings can be concatenated: Function example

Fig. 17: Example of concatenation in eval function

Formatting of an eval that contains multiple references: Function example

Fig. 18: Example of formatting of eval that contains multiple references

warning

If eval contains multiple references, formatting can only be done using an html tag inside the function. This option is more suitable for the more experienced users. In newer versions, this approach might not work; therefore, I recommend splitting eval as shown in the example in Fig. 20.

This case of formatting multiple references does not work: Function example

Fig. 19: Example of wrong formatting of eval that contains multiple references

warning

If eval contains multiple references, it can only be formatted as a whole. You cannot use multiple formatting in one eval, the format of the last character in the parenthesis will always be taken into account.

There is an example of a valid solution of formatting to the example above without using html tags: Function example

Fig. 20: Example of formatting of eval that contains multiple references without html tags

Formatting examples: Function example

Fig. 21: Examples of formatting of eval function

It is also possible to apply a function: Function example

Fig. 22: Example of applying function in eval function to get string length

Function example

Fig. 23: Example of applying function in eval function to get value of string attribute in upper-case characters

Basic mathematical operations can be applied to numeric attributes: Function example

Fig. 24: Examples of applying basic mathematical operations to numeric attributes

warning

Do not use a character – (long dash) like a minus!

Image​

Valid notation: odd marks

Invalid notation: pair marks

There you can find the rest of the image function explanation and examples.

HTML function​

Valid notation: pair marks

Invalid notation: odd marks

HTML can also be inserted if the conditions are met.

The conditions are:

  • HTML must be valid.
  • It must always be wrapped in the HTML root <html> </html> element.
  • The HTML placeholder must always be filled, otherwise the template will throw an error.
  • Unable to apply optional data entry ( )!.
  • HTML marks (tags) in Word must be pair, or an error will occur.
  • There must not be an odd number of tags in html, each tag must form a pair. This also applies to odd tags such as <br> , <hr> etc.

Example of static HTML: Function example

Fig. 25: Example of static HTML

Example of HTML reference from data model: Function example

Fig. 26: Example of HTML reference from data model

tip

HTML functions can be useful for generating tables.

IF ELSE condition​

Valid notation: Function example

Fig. 27: Valid notation of IF ELSE function

Use case schema: Function example

Fig. 28: Use case of IF ELSE function

Examples: Function example

Fig. 29: Examples of IF ELSE function

warning

IF nested within IF is not possible!

Switch case​

Valid notation: Function example

Fig. 30: Valid notation of Switch case function

Use case schema: Function example

Fig. 31: Use case of Switch case function

Examples: Function example

Fig. 32: Example of Switch case function

Repeat​

Valid notation: Function example

Fig. 33: Valid notation of Repeat function

Example without indentation: Function example

Fig. 34: Example of Repeat function without indentation

Example with indentation: Function example

Fig. 35: Example of Repeat function with indentation

Example of combining repeat and if with an additional size function application: Function example

Fig. 36: Example of combining Repeat and If functions with an additional size function application

Example of an additional filtering function application: Function example

Fig. 37: Example of Repeat function with an additional filtering function application

Checkbox​

There are two types:

  • activeCheckBox
  • checkBox

Valid notation: odd marks

Invalid notation: pair marks

Example of an active checkbox: Function example

Fig. 38: Example of an active checkbox

Example of a passive checkbox: Function example

Fig. 39: Example of an passive checkbox

Table function​

Valid notation: Function example

Fig. 40: Valid notation of Table function

Example: Function example

Fig. 41: Example of Table function