ColdFusion MX and iText for PDF Generation
One of the greatest powers of Adobe's ColdFusion MX server is the
ability to utilize Java libraries for additional functionality.
I recently had a friend ask me if I could generate documents based on
data collected from a web form. Sure thing, no problem. Then he showed
me his template that he wanted the data inserted into. It wad a highly
stylized Microsoft Word document with embedded images. I told him that
it wouldn't be as simple as I had originally planned (I was thinking of
outputting RTF files at first), and I asked if Adobe PDF files would
work, which he answered "yes" to.
I quickly realized that while I have been enjoying working within my
employer's ColdFusion MX 7 server environment with it's built-in PDF
generation thanks to the CFDOCUMENT tag, my own server is only running
version MX 6 and I am lacking the capabilities... Until I take
advantage of a 3rd party component at least.
I had heard of stuff like CutePDF and I wanted to get more info. So I
turned to mankind's best friend, Google.
I ran across a buddy, and former co-worker, of mine, Aaron Johnson's
blog where he wrote a how-to on generating PDFs from scratch using
ColdFusion and the free Java library iText. This wasn't exactly what I
wanted as I was looking to setup pre-defined regions in a PDF template,
then generate copies populated with dynamic data.
This was something I knew that something out there could do, I just
didn't know how.
Looking into iText some more I found that it had what is called a PDF
Stamper that could populate PDF form fields with data. "PERFECT", I
thought. But my searches to find a ColdFusion example of using the
Stamper showed me that there wasn't a whole lot of people doing this.
I did however find a pure Java example of using the Stamper how I
wanted, and using some common sense, Aaron's ColdFusion code as a base,
and about an hour of trial and error I was able to get a working
ColdFusion/iText app going.
I am here today to spread the knowledge.
First things first. Install iText by downloading the Java JAR file from
their web site and placing it in your ColdFusion /lib/ folder. Now
Stop/Start the ColdFusion server service and you are done with step
one. iText is now installed.
Next you need a PDF with form fields to work with. You can create your
own or use this one here: SimpleRegistrationForm.pdf (taken from iText example page).
And finally here is the CFML to load the PDF template, set the values
for the PDF form fields, and save the results to a new PDF:
<cfscript>
//define path and file name of the PDF template with form
pdfFile=expandPath("SimpleRegistrationForm.pdf");
//define the name of my output file
newFile=expandPath("SimpleRegistrationForm_output.pdf");
//create the output file
fileIO=createObject("java","java.io.FileOutputStream").init(newFile);
//load the template PDF with the iText PDF reader
reader = createObject("java","com.lowagie.text.pdf.PdfReader").init(pdfFile);
//load the template into the iText PDF stamper and specify the output file
pdfStamper = createObject("java","com.lowagie.text.pdf.PdfStamper").init(reader, fileIO);
//create a form object to reference
pdfForm = pdfStamper.getAcroFields();
//set the form fields
pdfForm.setField("name", "John Doe");
pdfForm.setField("email", "john@gmail.com");
pdfForm.setField("address", "123 Sesame St.");
pdfForm.setField("postal_code", "90210");
//optional, this will "flatten" the form in the output file to convert all the editable form fields to plain text, or you can remove this to leave them as editable form fields
pdfStamper.setFormFlattening(true);
//end
pdfStamper.close();
//you are done now.
</cfscript>
You can download the output file here: SimpleRegistrationForm_output.pdf
As you can see I am using the setField method to set the values of the
form fields. And I have to name each field by how they were named in
the original PDF. If by chance I didn't know all the names I could just
use CFDUMP and get the form field names all returned to me:
<cfdump var="#pdfForm.getFields()#">
A great thing about this is that you can have non-developers handle
creating the PDF templates for you. Using the Adobe Acrobat software it
is very easy to define form fields within your document.
Even with CFMX 7's added built-in PDF support, I think iText is a
welcome addition giving you even more functionality. And it's priced
right.