Machine generation of PDF files the easy way – part II

In my previous article, I went through the basics of what tools would be necessary to use Apache FOP to create PDF files.

In this second example will extend upon my XSL-FO script to add a header and footer to the output. The final result will generate this header and footer on all pages of the report and will look like this.

data2

The original example has been pretty much the simplest possible case. Every page is just one big rectangle and each time that a person record shows up it will be output. It is actually magically simple. If there were hundreds of names, then they will be displayed and as they approach the defined margin it would automatically break to the next page.

In the previous article, I mentioned that the report definition only contained the report body. I didn’t actually mention other things that it could have included. The two new things that are included in this example contain is both the region-before and the region-after sections. These are used for adding a header and footer to the report.

       +---------------------------------------+
       |              region-before            |
       +---------------------------------------+
       |   |                               |   |
       | r |                               |   |
       | e |                               | r |
       | g |                               | e |
       | i |                               | g |
       | o |                               | i |
       | n |          region-body          | o |
       | - |                               | n |
       | s |                               | - |
       | t |                               | e |
       | a |                               | n |
       | r |                               | d |
       | t |                               |   |
       |   |                               |   |
       +---------------------------------------+
       |              region-after             |
       +---------------------------------------+

It is important to remember that this mock up (above) is excluding the page margins. The 2cm page margins defined by the page would be within the region-body.  It is also possible any or all of these four other regions also have a margin.

Adding the header/footer is as simple as adding these two “regions” to the definition at the same location as the definition of the region-body.

          <fo:region-body margin-top="1cm" margin-bottom="1cm"/>
          <fo:region-before region-name="myHeader" extent="2.0cm"/>
          <fo:region-after region-name="myFooter" extent="1.5cm"/>

The actual definition of what we would expect to see in in our header and footer regions is defined in the page-sequence along with the region body.

        <fo:static-content flow-name="myFooter">
          <fo:block font-family="Helvetica" text-align="left" font-size="7pt" color="black">
          __________________________________________________________________________________________________________________________________
          </fo:block>
          <fo:block font-family="Helvetica" text-align="left" font-size="7pt" color="gray">
		We deliver the most interesting data which can be considered almost factual.
          </fo:block>
        </fo:static-content>

This example shows what the footer should look like and it will be used in the region after portion of the page as was described in with the rest of the simple-page-master.

This could actually be simpler, it is not necessary to define every attribute on every block. It would have been sufficient to define the font-family on the block for the entire footer and within that have one or more blocks with varying attributes for the lines that are displayed.

One additional change to the xslt form in general was how the listtype value was retrieved from the data. This time rather than specifying the entire hard coded path, I simply pluck the value when I am processing that particular field.

This only works because when designing the xslt I knew that the listtype field would exist once in my input and it would be located just prior to my list data. If this field happened to be in my datafile after my person data my list header would incorrectly show up after my list.

Download source and pdf for this example

Download files

The next set of changes for this can be found in part III.

This entry was posted in programming and tagged , , , . Bookmark the permalink.