Generating large PDF documents with Apache FOP

Generating large PDF documents with Apache FOP
Photo by Emile Perron / Unsplash

Some days ago I had trouble with generating large PDF documents (> 2000 pages) with Apache FOP. The problem was the memory consumption while rendering the document. In my opinion, it was not an acceptable solution to increase the JVM memory > 2GB. So I had to find a way to optimize my templates.

Fortunately, on the FAQ list of Apache FOP is a section about Memory Usage, which gives some very useful hints on optimizing the template.

In my case, I had defined one page-sequence element for the whole document, but logically the PDF document contained multiple documents with several pages. So it was quite easy to define an own page sequence for each logical document. With this little modification in my template, the memory usage shrank from about 2GB under 60MB and the rendering process finished notable faster.

The initial template looked something like this:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template match="/">
  <fo:root>
    <fo:page-sequence master-reference="A4">
      <xsl:apply-templates select="Document" />
    </fo:page-sequence>
  </fo:root>
</xsl:template>

<xsl:template match="Document">
  <!-- Page content goes here -->
</xsl:template>

</xsl:stylesheet>

After optimizing the template it looked like this:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template match="/">
  <fo:root>
    <xsl:apply-templates select="Document" />
  </fo:root>
</xsl:template>

<xsl:template match="Document">
  <fo:page-sequence master-reference="A4">
    <!-- Page content goes here -->
  </fo:page-sequence>
</xsl:template>

</xsl:stylesheet>