Creating PDF's From JSON templates
This is a guide on how to use BOOST.PDFBuilder - a minimal and fast PDF creation tool. BOOST.PDFBuilder can either be used as a Java layout library, or used to create PDF's from user defined templates. This guide mostly focuses on the latter. See javadocs for the former. The templates are JSON objects adhering to the standards specified in this document.
Getting Started
To compile a PDF, you only need the following lines in Java:
import com.luqon.boost.PDFBuilder;
PDFBuilder pdfBuilder = new PDFBuilder();
JsonObject myTemplate;
JsonObject myData;
PDDocument myDocument = pdfBuilder.generatePDF(myTemplate, myData);
myDocument.save("FilePath");For the above code to work, a few things are neccessary.
Fonts
- Font files must be provided to BOOST.PDFBuilder in a designated folder.
- The directory can be changed in the config.properties. Default is "fonts" with a relative path.
- Fonts must be true type fonts with file name .ttf
Color Profiles
- A color profile is neccessary.
- BOOST.PDFBuilder will use the color profile from the file
sRGB Color Space Profile.icm. - Do not change this, as some properties related to it are hard coded, and there should never be a need to change it.
Configuring Document
The following properties must be present on the first level in the JSON.
Document Settings:
- Requires an object
"margins"containing the margins specified in points. - Requires an object
"pageSize"containing the size of the page. Valid options are:A4, 123mm, 123, where 123 will be in points for the last case. - Requires a string
defaultFontcontaining the name of the default font to be used. - Requires a string
defaultFontSizecontaining the default font size. - Optional:
"showPageNumbers": true. Default is false.
json"documentSettings": { "margins": { "top": 50, "right": 50, "bottom": 50, "left": 50 }, "pageSize": { "height": "A4", "width": "A4" }, "defaultFont": "HelveticaNeueLTCom-Lt", "defaultFontSize": 12, "showPageNumbers": true }- Requires an object
Fonts:
- the name of the fonts that you plan to use for this document must be given as a string array.
- Use the names of the files, without the .ttf extension.
- Example:
"fonts": ["arial", "HelveticaNeueLTCom-Lt", "HelveticaNeueLTCom-Bd"]
Adding content
To add content, you create a layoutObject, which is an object that will be rendered to the PDF. They are all placed in the array layoutObjects. Many different options are possible. So we start by giving a simple 'Hello World' example.
Hello World Example
{
"documentSettings": {
"margins": {
"top": 50,
"right": 50,
"bottom": 50,
"left": 50
},
"pageSize": {
"height": "A4",
"width": "A4"
},
"defaultFont": "HelveticaNeueLTCom-Lt",
"defaultFontSize": 20
},
"fonts": [ "HelveticaNeueLTCom-Lt"],
"layoutObjects": [
{
"type": "paragraph",
"text": "Hello World!",
"width": 100
}
]
}General Properties for all Layout Objects
type: valid options are["paragraph", "blankSpace", "horizontalDivider", "table", "footer"]. Image is likely to be added later, as the core API already has support for it.position: If you want to override the built in LayoutManager, you can do so by adding an objectpositionwith absolute coordinates (pts) from the bottom left corner of the layoutObject. This is because Apache PDF-box starts from the bottom left corner. An example:"position": { "x": 500, "y": 500 }. This even ignores the page margins. Use with care!text: a property of most layout objects. In the next section, it is described in more detail.location: most elements support a location property. Valid options are["LEFT","CENTER", "RIGHT", "WINDOW"]. Left and right are self explainatory. Usingcenter, the actual width of the object is computed, not the specified width, as an object might not occupy all its allocated space.Window, when used on a document width A4 width will be position the left edge of the object to align with a window in a standard swedish envelope.centering: most elements containing text allow specifying the centering. Options are["LEFT", "CENTER", "RIGHT"].
Parsing Data, Math Expressions and Formatting
Parsing Data
BOOST.PDFBuilder allows for dynamic data in the PDF-generation. This data is provided as a JsonObject in the second argument of the generatePDF(JsonObject template, JsonObject data)- function of the PDFBuilder. To include dynamic data, the format is
"text": "Dynamic data is inserted like this: {{fieldName}} ". Here is a Hello-World example with dynamic data. Template:
{
"documentSettings": {
"margins": {
"top": 50,
"right": 50,
"bottom": 50,
"left": 50
},
"pageSize": {
"height": "A4",
"width": "A4"
},
"defaultFont": "HelveticaNeueLTCom-Lt",
"defaultFontSize": "12"
},
"fonts": ["HelveticaNeueLTCom-Lt"],
"layoutObjects": [
{
"type": "paragraph",
"text": "{{myDataField}}",
"width": 100
}
]
}Data:
{
"myDataField": "Hello World!"
}BOOST.PDFBuilder supports dot separated paths. Consider the following data:
{
"myFirstObject": {
"field1": "Hello",
}
}BOOST.PDFBuilder also supports ?if an object might be null. In that case, the expression will result in an empty string. Thus writing
{{myFirstObject.field1}}
{{myFirstObject.field2?}}will render Hello, since the field2 doesn't exist in this data object. The question mark is not as strict as in other languages, and will make any null value return an empty string.
Mathematical Expressions
Everything placed in between dollar signs will be interpreted as a math expression and evaluated. The supported math expressions are only +, -, *, and /. It is thus very basic. It does support dynamic data, thus writing
${{field1\}}*{{field2}}$is valid. First, the values of field1 and field2 are inserted, then the expression is evaluated.
Formatting
BOOST.PDFBuilder supports custom formatting for numbers, dates and strings. For dynamic data, the syntax is
{{fieldValue:format}}For a math expression, the syntax is instead
$expression$ | formatValid formatting options are:
- C-style number formatting options.
%.2fmeans a float with 2 digits etc. See Java'sString.format()method for more details. - Date(time) formatting. Just provide a date-time format. Normally
yyyy-MM-ddis what you need. See Java'sdateTimeFormatterfor more details. - String formats. We support:
upper,lower,capitalizeandtrim. They mean uppercase, lowercase, capitalize first letter and remove leading and trailing white space respectively.
Different Types of Layout Objects
Paragraph
Our implementation of a paragraph is a very lightweight one. In its most simple usage, only the text and width must be specified. The paragraph has automatic line-break if the width is exceeded.
Properties
type: "paragraph". Makes this layoutObject a paragraphtext: the text to be displayed. See above sections for more details on formatting and dynamic data etc.font: a string containing the name of the desired font. If not present, the document level default font is used.fontSize: a number containing the font size, defaults to document level font size.width: a mandatory width of the paragraph with the unit points.location: the location of the paragraph, see general properties.centering: the centering of the paragraph, see general properties.
Blank Space
In general, the layoutmanager of BOOST.PDFBuilder works as follows: it starts from the top and works its way down. The logic is that you specify the width of something, and then that object may occupy as much space vertically as neccessary. Sometimes you want to give a little bit of extra space between entities, and that is where blank space comes in. It is also possible to add negative blank space, effectively moving the cursor higher up on the page.
Properties
blankSpace: makes this layoutObject a blank space.height: the height of the blank space, unit points. It can be negative
Horizontal Divider
This is just a black line extending from the left margin to the right.
Properties
horizontalDivider: makes this layoutObject a horizontal divider.thickness: specifies the thickness of the line. It is mandatory!
Footer
This is just a special version of a paragraph, and the properties are the same as that of a paragraph. The only difference is that it is added from the bottom.
Properties -footer: makes this layoutObject a footer.
Table
This is probably the most important element of BOOST.PDFBuilder. It is highly configurable, and can also be used as a template on how to render a JsonArray of data.
Properties
table: makes this layoutObject a table.widths: an array defining the widths of the columns. It implicitly also defines the number of columns. The default unit is points. An example of a table with three columns each 100 pts wide:"columnWidths": [100,100,100]. It is also possible to define widths as a percentage of the document width between the left and right margin. Thus `"columnWidths": ["50%","50%"] will make the table occupy all the space from the left to the right margin.rows: a JsonArray containing the data to be rendered. Will be explained in more detail.fontSize: sets a default font size on the table level.font: sets a default font on the table level.splitable: (true/false). Default true. Defines wether the table can be split or not. If"splitable": trueand the table does not fit on the current page, the layoutmanager will create a new page and add the table.spacing: sets the spacing between each row (pts). Default value is 1 point.location: sets the tables location on the page. See general properties. Default for a table iscenter.grid. Add an optional black grid to the table. Valid options are:["full","horizontal","minimal","outline"]. A full grid draws a box around each cell. A horizontal grid contains only contains horizontal lines. A minimal grid only draw a line below the header. An outline grid is a black box around the entire table.
These are all the table level properties of table, but they can contain properties on row and cell level.
Row level properties The following properties apply on row level.
type: sets what type of row this is. Valid options aretextortemplate.Templatewill be explained in detail later.font: sets the default font on the row level. Usefull for creating a header row.fontSize: sets the default font size on the row level.spacing: defines how much space (pts) there should be from the line above.cells: a JsonArray containing the actual cells with data or text to be added. Must of course be of the same length as theColumnWidths-array.
Cell level properties The following properties apply on cell level.
text: works just as usual.font: cell level font.fontSize: cell level font size. Both this and the fonts defaults to row level which in turn defaults to table level which in turn defaults to document level.centering: sets the centering. Default is left.
Using the table template functionality The table template allows you to couple a table to a JsonArray with the data you want to display. Handy for creating invoices with a variable amount of data. Below are all its properties.
field: sets the name of the JsonArray containing the data that will be used in the template.cells: Here you define how you wish for the data to be displayed. Right now, cell level centering is not supported.
Here is a complete example of how a table with custom data can be created.
{
"type": "table",
"location": "CENTER",
"font": "HelveticaNeueLTCom-Lt",
"fontSize": "9",
"columnWidths": ["90", "120"],
"spacing": "3.0",
"grid": "minimal",
"rows": [
{
"font": "HelveticaNeueLTCom-Bd",
"fontSize": "9",
"spacing": "7",
"cells": [
{"type": "paragraph", "text": "Artikelnr" },
{"type": "paragraph", "text": "Benämning" },
]
},
{
"type": "template",
"field": "orderLines",
"template": {
"cells": [
{"text": "{{itemSellersItemIdentificationId}}", "type": "paragraph"},
{"text": "{{itemName}}", "type": "paragraph"}
]
}
}
]
}The data object can look like this:
{
"orderLines": [
{
"itemName": "Testitem",
"itemSellersItemIdentificationId": "1",
}
]
}