08
Sep
05

Making labels with FOP

Not many people have ventured into generating PDF documents from XML yet, but it's actually not too difficult if you are familiar with XML or HTML. I recently had to create thousands of scannable ID cards and address labels from a database, and XSL-FO was the best way to get print quality results.

Avery 5160 style labelsAll you need is a copy of FOP (from the Apache XML Graphics Project). There is already good documentation on Apache's site and W3Schools, so I won't go into much detail here. Basically, you either write an XML file (like the one below) with everything FOP needs, or you can generate one from some kind of XML data source (like an XHTML page) using XSLT. Since my data was on a MySQL database, it was easier to just create the native input file with a little server-side code.

Anyway, here is some code to generate a sheet of Avery 5160 address labels. Of course if you want to use this for more than one label, you will need to add more table cells and rows, and make sure the XML is well formed.

<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="labels" margin="0.5in 0 0.5in 0.1875in" page-width="8.5in" page-height="11in">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>

<fo:page-sequence master-reference="labels">
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed" width="8.25in">
<fo:table-column column-width="2.74975in"/>
<fo:table-column column-width="2.74975in"/>
<fo:table-column column-width="2.74975in"/>
<fo:table-body>
<fo:table-row height="1in">
<fo:table-cell background-repeat="no-repeat" margin-right="0.15625in" padding="0 0.1in 0 0.3in" display-align="center">
<fo:block font-size="10pt" text-transform="capitalize"><![CDATA[$attention_to]]></fo:block>
<fo:block font-size="10pt" text-transform="capitalize"><![CDATA[$mailing_name]]></fo:block>
<fo:block font-size="10pt" text-transform="capitalize"><![CDATA[$address]]></fo:block>
<fo:block font-size="10pt" text-transform="capitalize"><![CDATA[$address2]]></fo:block>
<fo:block font-size="10pt" text-transform="capitalize"><![CDATA[$city, $state $postal_code]]></fo:block>
<!-- As of FOP v0.20.2, text-transform is not yet supported. -->
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
</fo:root>

Say something: