In this blog post I will take a short break from design patterns to look at something completely different. If you are a developer like me chances are you have never heard of PDF/А. So lets start with the basics:

What is PDF/A?

PDF/A is an ISO-standardized version of PDF (i.e. Portable Document Format) which is specialized for use in archiving and long-term preservation of electronic documents.

This is achieved by embedding all the information (such as fonts and color palettes) required to view a document in the PDF file itself. Because it is aimed at archiving documents it is often used by governments as a standard for archives which are required by law. Even when this is not the case, it might still be a good idea to convert your PDF files to PDF/A if they are kept for longer periods of time (e.g. more than a year).

Understanding document generation in Mendix

By default documents generated using Mendix standard functionality (a.k.a. Document Templates) are not PDF/A compliant. To see how we can achieve compliance we first need to take a closer look at how Mendix generates documents. Here is a high level view of the document generation process:

  1. developer creates a document template and adds things like text, images and tables and specifies margins, styling and fonts.

  2. Mendix combines the dynamic data coming from Mendix objects together with the template to create an XML file that conforms to a specification called XLS-FO. Here is a good example of how such a file might look like.

  3. A library called Formatting Objects Processor or FOP for short is used to convert an XLS-FO file to PDF or other printable formats.

It so turns out that the library FOP comes with a wealth of configurable options which also include PDF/A compliance - If only there was documentation on

How to change the configuration that Mendix uses for document generation?

After some reverse engineering with the help of JD I established the following:

  1. By default, Mendix uses its own configuration file, which is stored at C:\\Program Files\\Mendix\\<mx version>\\runtime\\lib\\fop.xconf. Editing this file will change the configuration but will only work on your local machine, because the Mendix distribution that is used in the cloud does not have your local changes.

  2. If Mendix finds a file named fop.xconf in the resources folder of your project it will use that instead of the default. Jack pot!

Now that we have figured out how to change the configuration, we can finally get to the main point for this blog

TL;DR; How to generate PDF/A compliant documents in Mendix?

  1. Create a file fop.xconf in the resources folder of your project with the following contents:
<?xml version="1.0"?>
<fop version="1.0">

  <!-- throw errors if the document is not PDF/A compliant -->
    <renderer mime="application/pdf">
      <!---1b is the most minimal mode of compliance for PDF/A. 
           More details here <> -->

        <!-- all used fonts need to be embedded -->
        <font kerning="yes" embed-url="arial.ttf" embedding-mode="full">
          <font-triplet name="Arial" style="normal" weight="normal"/>
          <font-triplet name="ArialMT" style="normal" weight="normal"/>
        <font kerning="yes" embed-url="arialbd.ttf" embedding-mode="full">
          <font-triplet name="Arial" style="normal" weight="bold"/>
          <font-triplet name="ArialMT" style="normal" weight="bold"/>
        <font kerning="yes" embed-url="ariali.ttf" embedding-mode="full">
          <font-triplet name="Arial" style="italic" weight="normal"/>
          <font-triplet name="ArialMT" style="italic" weight="normal"/>
        <font kerning="yes" embed-url="arialbi.ttf" embedding-mode="full">
          <font-triplet name="Arial" style="italic" weight="bold"/>
          <font-triplet name="ArialMT" style="italic" weight="bold"/>
  1. Add any fonts you want to use in your document to the resources folder of your project and make sure they are properly embedded in fop.xconf. Follow the example for embedding of the Arial font from the code snippet above.

That is all. Hope you find this blog helpful!