Create pdf documents from liquid templates.

This library uses LiquidJS, Symbology, Bz-Date, btrz-formatter and PDFMake and link them together while adding some helpers to easily generate PDFs from templates.

The vesion of PDFMake has been inlined and modified to allow for text rotation.

Install

npm i btrz-pdf

Restrictions

The documents generated only uses Helvetica fonts.

Methods

Async method that returns a buffer, best used with Express to return the PDF in the response or to generate documents to be merged later on.

Parameters

name definition
liquidTemplate object representing a pdfmake document with valid liquidSyntax
data Object with data needed by the liquid template

Async method that combines buffers into PDF documents

Parameters

name definition
buffers An array of buffers

Async method using a cb to return a buffer, best used with Express to return the PDF in the response.

Parameters

name definition
liquidTemplate object representing a pdfmake document with valid liquidSyntax
data Object with data needed by the liquid template
cb A callback with the signature (err, buffer)

Async method that returns a promise with a PDF document

Parameters

name definition
liquidTemplate object representing a pdfmake document with valid liquidSyntax
data Object with data needed by the liquid template

Returns an empty PDFmake document definition with some default styles

{
  "defaultStyle": {
    "font": "Helvetica",
    "fontSize": 10,
    "lineHeight": 1.3
  },
  "styles": {
    "header": {
      "fontSize": 16,
      "bold": true,
      "margin": [0, 0, 0, 10]
    },
    "subheader": {
      "fontSize": 14,
      "bold": true,
      "margin": [0, 20, 0, 0]
    },
    "innerheader": {
      "fontSize": 12,
      "bold": true
    },
    "tableHeader": {
      "fontSize": 8,
      "bold": true,
      "margin": [0, 4, 0, 0]
    },
    "table": {
      "fontSize": 8,
      "margin": [0, 8, 0, 0]
    },
    "attachedTable": {
      "fontSize": 8
    },
    "cell": {
      "margin": [0, 4, 0, 0]
    },
    "cellError": {
      "margin": [0, 4, 0, 0],
      "color": "#FF0000"
    },
    "cellMoney": {
      "margin": [0, 4, 0, 0],
      "alignment": "right"
    },
    "cellMoneyError": {
      "margin": [0, 4, 0, 0],
      "color": "#FF0000",
      "alignment": "right"
    },
    "footer": {
      "fontSize": 8
    }
  },
  "content": []
}

Async method that returns a PDFmake document defintion after processing the template and the data

Parameters

name definition
liquidTemplate object representing a pdfmake document with valid liquidSyntax
data Object with data needed by the liquid template

Usage

  const btrzPdf = require("btrz-pdf");

  //Returns a PDF as data with Express
  async returnPDF(req, res) {
    try {
      const buffer = await PDF.returnPdfBuffer(template, data);
      res.setHeader("Content-Disposition", `attachment;filename="${filename}.pdf"`)
      res.setHeader("Content-type", "application/pdf");
      res.write(buffer);
      res.send();
      return; 
    } catch (err) {
      res.status(500).send(error);
    }
  }

  const btrzPdf = require("btrz-pdf");

  //Returns a PDF as data with Express
  async mergeAndReturnPdf(req, res) {
    try {
      const items = [item1, item2, item3];
      const buffers = Promise.all(items.map((item) => {
        data.item;
        return PDF.returnPdfBuffer(template, data);
      }))
      const result = await PDF.mergePdfBufffers(buffers);
      res.setHeader("Content-Disposition", `attachment;filename="${filename}.pdf"`)
      res.setHeader("Content-type", "application/pdf");
      res.write(result);
      res.send();
      return;
    } catch (err) {
      res.status(500).send(error);
    }
  }

  const btrzPdf = require("btrz-pdf");

  //Returns a PDF as data with Express
  async previewPdf(req, res) {
    try {
      PDF.returnPdfBinary(template, data, (error, binary) => {
        if (error) {
          res.status(500).send(error);
        } else {
          res.contentType("application/pdf");
          res.send(binary);
        }
      });
      return; 
    } catch (err) {
      res.status(500).send(error);
    }
  }

  const btrzPdf = require("btrz-pdf");

  //Returns a PDFmake document defintion from the template and the data
  async getLiquid(req, res) {
    try {
      const document = await PDF.toDocumentDefinition(template, data);
      res.send(document);
    } catch (err) {
      res.status(500).send(error.message);
    }
  }

Custom document defintions

Default is text not rotated.

You can add "direction": "rotate-right" to rotate the text and barcodes in the template 90 degrees. You can add "direction": "inverse" to rotate the text and barcodes in the template 180 degrees. You can add "direction": "rotate-left" to rotate the text and barcodes in the template 270 degrees.

You can use this new document properties to add headers or footers with page numbers and total pages. The use is the same for both. This properties need to be declared at the same level as the content property and not inside the content property.

"headerFn": {
        "text": " currentPage of pageCount",
        "style": "headerFooter"
}

"footerFn": {
        "text": " currentPage of pageCount",
        "style": "headerFooter"
}

In the example below assuming the header.content is the text “Page #” it will print something like this for the first page of a document with 5 pages.


Page # 1 of 5

Custom tags

Generates a barcode based on some data

Parameters

name definition required default
data The string to use to generate the barcode, it can be hardcoded or some of the ‘data’ given to the template Y  
type The barcode type N code128
height The barcode height N 30
width The barcode width N 200
margin A list of 4 values for the margin N 0,0,0,0

It will use the value of ticket.code to generate the barcode with all the defaults

 {% barcode ticket.code %} 

It will use the value given and use generate a ‘code11’ barcode with a height of 50 and a width of 300

 {% barcode 1234 code11 50 300 20,20,20,0 %}  

Supported types

It supports all types supported by https://symbology.dev/. While symbology supports QRCODE PDFMake also had support for QR natively and we recommend it.

Returns the proper str to transform into a QR code to be able to scan items with the drivers app

 {%- qrstr reservation -%}  //"https:///r/t/"
 {%- qrstr ticket -%}  //"https:///r/t/"

Parameters

name definition required default
type The type of object we will be generating the string for the qrcode N ticket

Valid types

reservation, ticket, paid_in, parcel, flexpass, ssr, redeemableItem

Returns a date formatted by the given format from a property of an object given to the liquid template data.

 {%- dateTime ticket createdAt -%}  //"12/21/2021 11:38 AM"
 {%- dateTime ticket createdAt mm/dd/yyyy hh:MM:ss -%}  //"12/21/2021 11:38:00"

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
propName The name of the property of the item (it should be a BzDate object) N createdAt
format A format object N providerPreferences defaults (see prereqs)

Prerequisites

There are some prerequisites to use any of the Date helpers. The data given to the liquid template requires the following object to be present

{
  "providerPreferences": {
    "preferences": {
      "dateFormat": "mm/dd/yyyy", //any date format string will do
      "timeFormat": "h:MM TT", //any time format string will do
      "timeZone": {
        "name": "(UTC-5:00) New York (United States), Toronto (Canada)",
        "daylight": true,
        "tz": "America/Toronto"
      } //any timezone as defined in BzDate will do
    }
  }
}

Convenience method that will default format to providerPreferenes.preferences.dateFormat

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
propName The name of the property of the item (it should be a BzDate object) N createdAt
applyTimeZone If you want to adjust the date with the account timeZone N true
 {%- dateF ticket createdAt -%}  //"12/21/2021"

Convenience method that will default format to providerPreferenes.preferences.timeFormat

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
propName The name of the property of the item (it should be a BzDate object or a time string) N createdAt
applyTimeZone If you want to adjust the date with the account timeZone N true
 {%- timeF ticket createdAt -%}  //"11:38 AM"

Convenience method that will calculate the expiration date for a reservation

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
format A format object N providerPreferences defaults (see prereqs)
 {%- expDate reservation -%}  //"12/21/2021 11:38 AM"

Convenience method that will calculate the arrival date for a reservation and will apply the arrival station timeZone if available

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- arrivalDate reservation -%}  //"12/21/2021"

Convenience method that will calculate the departure date for a reservation and will apply the departure station timeZone if available

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- departureDate reservation -%}  //"12/21/2021"

Convenience method that will calculate the arrival time for a reservation and will apply the arrival station timeZone if available

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- arrivalTime reservation -%}  //"11:38 AM"

Convenience method that will calculate the departure time for a reservation and will apply the departure station timeZone if available

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- departureTime reservation -%}  //"11:38 AM"

Convenience method that will calculate the arrival date for a reservation and will apply the arrival station timeZone if available

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- arrivalDateTime reservation -%}  //"12/21/2021 11:38 AM"

Convenience method that will calculate the departure date for a reservation and will apply the departure station timeZone if available

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- departureDateTime reservation -%}  //"12/21/2021 11:38 AM"

Convenience method that will calculate the arrival date for a reservation and will apply the arrival station timeZone if available. It will format the date using the humanDate property given to the template. humanDate can be either ‘mm’ or ‘dd’, default to ‘mm’.

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- humanArrivalDate reservation -%}  //"Tue Dec 21, 2021"

Convenience method that will calculate the departure date for a reservation and will apply the departure station timeZone if available. It will format the date using the humanDate property given to the template. humanDate can be either ‘mm’ or ‘dd’, default to ‘mm’.

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- humanDepartureDate reservation -%}  //"Tue Dec 21, 2021"

Convenience method that will calculate the arrival date for a reservation and will apply the arrival station timeZone if available. It will format the date using the humanDate property given to the template. humanDate can be either ‘mm’ or ‘dd’, default to ‘mm’.

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- humanArrivalDateTime reservation -%}  //"Tue Dec 21, 2021 11:38 AM"

Convenience method that will calculate the departure date for a reservation and will apply the departure station timeZone if available. It will format the date using the humanDate property given to the template. humanDate can be either ‘mm’ or ‘dd’, default to ‘mm’.

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- humanDepartureDateTime reservation -%}  //"Tue Dec 21, 2021 11:38 AM"

Convenience method that will default format based on the humanDate property given to the template as part of the data object. humanDate can be either ‘mm’ or ‘dd’

(humanDate === "mm") ? "ddd mmm dd, yyyy" : "ddd dd mmm, yyyy"

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
propName The name of the property of the item (it should be a BzDate object) N createdAt
applyTimeZone If you want to adjust the date with the account timeZone N true
 {%- humanDate ticket createdAt -%}  //"Tue Dec 21, 2021"

Convenience method that will default format based on the humanDate property given to the template as part of the data object. humanDate can be either ‘mm’ or ‘dd’ plus the providerPreferenes.preferences.timeFormat

(humanDate === "mm") ? "ddd mmm dd, yyyy" : "ddd dd mmm, yyyy"

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
propName The name of the property of the item (it should be a BzDate object) N createdAt
applyTimeZone If you want to adjust the date with the account timeZone N true
 {%- humanDateTime ticket createdAt -%}  //"Tue Dec 21, 2021 11:38 AM"

This tag will parse “some” HTML code and try to generate compatible PDFmake text objects.

Parameters

name definition required default
property this will be “evaluated” from the data provided to the liquid template Y  
 {% h ticket.lexiconKeys.terms %}  //If will get the string in the property and parse it

Supported html tags

h1 - will generate a text node with “style”: “header” h2 - will generate a text node with “style”: “subheader” h3 - will generate a text node with “style”: “innerheader” b - will generate a text node with “bold”: true i - will generate a text node with “italics’”: true

This tag generates an horizontal line

Parameters

name definition required default
width the width of the line N 500
weight the weight of the line N 1
rgb the colour of the line, either a rgb or hex value or read from a data property as hex N 0,0,0
 {%- hline 475 2 255,112,0 - %}  //Generates an svg line with the width, weight and colour given
 {%- hline 475 2 providerPreferences.preferences.colors.brandBackground - %}  //Generates an svg line with the width, weight and colour given
{
  "svg": "<svg height='2' width='100'><line x1='0' y1='0' x2='1000' y2='0' style='stroke:rgb(255,112,0);stroke-width:2' /></svg>",
  "width": 475
}

Returns a translation based on a key, it can use a string or variables from the data given to the liquid template

Prerequisites

There are some prerequisites to use the t tag. The data given to the liquid template requires a localizer object with a .get(key) method that can return the translation. The implementation is up to you.

Parameters

name definition required default
property the key for the lexicon Y  
 {% t 'issued' %}  //Will return the value on the lexicon with the 'issued' key
 {% t fare.lexiconKeys.description %}  //Will return the value on the lexicon with the key stored in the `data.fare.lexiconKeys.description` property

Split lines or hardcoded text that may include carriage returns

Parameters

name definition required default
liquid expression A liquid expression that will be evaluated and each line will be converted on a text node Y  
style A style defined in the document to apply to the resulted text nodes N  
" {% txt operatingCompany.infoOnPrintedTicket small %} " //Given that ticket.total is 2800000 returns "28.00"

Returns a money value

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
propName The name of the property of the item N total
" {%- money ticket total -%} " //Given that ticket.total is 2800000 returns "28.00"

Adds the values of a property in objects in a collection and returns the total as a money value

Parameters

name definition required default
item.propName An object in the data given to the liquid template N ticket.taxes
innerPropName The name of the property in the objects in the collection N calculated
" {%- moneyReduce ticket.fees subTotal -%} "

Returns the currency name based on the displayCurrency of the item provided and the account configuration. If the item provided is a currency, it will just use that currency,

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- curcyName ticket -%} ",

Returns the currency symbol based on the currency used to paid the item or the default currency given in the providerPreferences.preferences.supportedCurrencies[0]

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- curcySymbol ticket -%} ",

Returns the currency ISO code based on the currency used to paid the item or the default currency given in the providerPreferences.preferences.supportedCurrencies[0]

Parameters

name definition required default
item An object in the data given to the liquid template N ticket
 {%- curcyIso ticket -%} 

Returns the amount in letters given in the property (amount should follow US notation, uses “.” for cents). It can translate values using the lang and localizer

Parameters

name definition required default
stringAmount A string with the amount Y  
 {%- toLetters '100.50' -%}  // One hundred with fifty cents
 {%- toLetters '123' -%}  // One hundred and twenty three

Given a URL for an image will encode into base64 and return in a consumable way for makePDF, only supports png and jpeg

Parameters

name definition required default
object.property The property should have a fully qualified URL to an image Y  
 {%- httpImg brand.logos.default -%}  // data:image/png;base64,77+9UE5HDQoaCgAAAA1JSERSAAA...