abacusfi / pdf-filler

Fills out AcroField-based form PDFs from JSON-encodable objects.

Version Matrix


Build Status

Fills out AcroField-based form PDFs from JSON-encodable objects.

There are two steps to using this library effectively:

  1. Prepare an AcroFields-compatible form and save as a PDF
  2. Use pdf-filler to fill out the form with the given form fields.


Preparing a form

At Abacus, we use LibreOffice Writer to prepare the forms.

Let's say you have the following JSON:

  "name": "Ian Macalinao",
  "age": 120

pdf-filler defines a mapping between the JSON fields and the form fields prepared in LibreOffice. The form creation process is drag-and-drop; see https://www.youtube.com/watch?v=cPI5OLS2B4s for more info on how to do this.

Form field names follow a modified version of JSONPath which takes type into account. In this example, name would be B$.name.

Due to some constraints in AcroFields, you must use angled brackets (<, >) instead of square brackets ([, ]) when accessing arrays. You can read the tests for more information on what JSONPath syntax is supported.

An example form is available in the fixtures/ directory.


The code is very simple:

  template = new File("template.pdf"), // from LibreOffice export
  out = new File("output.pdf"), // Output file
  data = myObj // Circe-encodable object

The signature of this function is:

def fill[T: Encoder](
  template: File,
  out: File,
  data: T,
): IO[Either[FillError, Unit]]

Encoder comes from Circe. Make sure you have an implicit instance of this in scope.

The IO monad return type comes from cats-effect -- if you are unfamiliar, you should go to their documentation.

FillError is an error that may result from filling out the form, e.g.

  • The paths in the form are not valid JSONPaths
  • The JSON type declared is not the same as the actual type
  • You used unsupported JSONPath syntax