The ability to programmatically access and manipulate PDF forms from within ColdFusion has been requested since, well, since we first demonstrated PDF generation abilities in ColdFusion MX 7. At CFUNITED a few weeks ago, Jason Delmore (ColdFusion Product Manager) demonstrated a planned ColdFusion “Scorpio” tag named which he used to populate (pre-fill) and extract values from a PDF form.
Scorpio is scheduled to be released in 2007. So what to do if you need PDF form support in ColdFusion right now? Well, here’s a solution:
Adobe has a Java API named XPAAJ (which stands for XML/PDF Access API for Java). The API can be used to:

  • Extract and insert PDF form field data.
  • Convert PDF documents to XDP format.
  • Access PDF metadata and file attachments.
  • Add, replace, and delete embedded data objects, file attachments, and annotations.
  • Obtain PDF file properties.
  • … and more.

Until a few days ago the XPAAJ license restricted use of the API to customers with licensed copies of LiveCycle servers. But that license has been updated to include other Adobe servers, including ColdFusion. As such, if you have a licensed copy of ColdFusion you may register and download XPAAJ and use it with ColdFusion.
Of course, using XPAAJ from within CFML code requires writing ColdFusion Java code. And so, to make life easier for us CFers, I wrote a Custom tag named which makes it really easy to get and set PDF form field values. Want to pre-fill a PDF form? You can use this code:










Extracting PDF form field values is just as easy:






is not as powerful or capable as Scorpio’s planned tag family, but it’ll help you in the interim.
To use you must download and install XPAAJ.jar from the LiveCycle Developer Center XPAAJ page (you will need to register and accept the license before doing so). XPAAJ comes with extensive documentation and examples (none of which are actually needed to use , although if you want to use XPAAJ to do more, this is all of the documentation you’ll need). Then you’ll need the attached ZIP file (see the download link below) which contains the Custom Tag, documentation, and a CFML example.
Enjoy!

99 thoughts

  1. FDF is used for forms created with Adobe Acrobat… The XPAAJ library is to be used with forms created with LiveCycle Designer.
    Although, the form file name is the same, PDF, the technology underneath that file format is different… For Acrobat forms, its PDF, but for forms created with LiveCycle Designer, its XDP.
    Mike

  2. Ben,
    I was wondering how the new tag stacks up performance-wise with something like IText which is what we currently use. Using this tag would be much easier for us but we do a lot of merging of PDF documents so it is very important to us that performance is equivalent and hopefully better than IText. I have a hunch it will be about the same. Thanks.

  3. Matt,
    I’ve never used iText at that level, so can’t really compare. I can tell you that XPAAJ is really fast. First request takes a moment (while Java classes are loaded and initialized) but subsequent requests fly.
    — Ben

  4. Can we pleeeeeease keep tags consistant!!
    Extend <CFDOCUMENT> please. The last thing the world needs is another CF tag!!
    You’ve created:
    <CFDOCUMENT TYPE="PDF" />
    <CFDOCUMENT TYPE="FlashPaper" />
    Just Use:
    <CFDOCUMENT TYPE="PDF">
    <CFDOCUMENTPARAM NAME="ProjectTitle" VALUE="My Project">
    </CFDOCUMENT>
    What about?
    <CFDOCUMENT TYPE="OpenXML" />
    <CFDOCUMENT TYPE="Custom" COMPONENT="components.myownone" />

  5. My last comment wasn’t so much in consideration of this ‘custom’ tag, but the new prototypes coming out of Adobe and the rumblings from internal sources of a <CFPDF> tag in Scorpio.
    Either use CFDOCUMENT (preferred) or use <CFPDF> and <CFFLASHPAPER> and lose the cfdocument tag, not both!! (since you already have <CFDOCUMENT> you may as well extend it!!

  6. Chris,
    I am one of the biggest opponents of tag creep, so as a rule I agree with the sentiment. But not in this example. CFDOCUMENT is all about creating new generated content, PDF or FlashPaper for now. It has nothing to do with populating an existing form or extracting data from a form. And trying to make that existing tag do this will require too many attributes and actions and the simplicity of a tag like CFDOCUMENT will be lost. Think about it, CFDOCUMENT takes a body which is the content to be rendered, you don’t need or want that for form fill in. CFDOCUMENT has tags for headers and footers which don’t apply to form fill-in. CFDOCUMENT has no way to accept name=value pairs, so you’d need to add that. And there is no return value from CFDOCUMENT generation which you’d need … So, nope, not in this case. But in many others, yes, we are very cautious when it comes to adding tags to CFML.
    — Ben

  7. What other Adobe tools would you recommend for creating PDF Forms? I was specifically looking @ Adobe Acrobat and Adobe Designer. I wasn’t sure what if anything I would need to purchase to create editable pdf documents. Thanks

  8. Hi
    I am trying this out on a new development installation of CF7. I have added the jar file to wwwroot/cfide/classes folder and the wwwroot/web-inf/classes folder. I get a class not found: com.adobe.pdf.PDFFactory error.
    Any ideas
    Thanks

  9. Joe,
    It’s not going to find the JAR file automaically in that folder. Try putting it in its own folder (at least for testing) and add that path to the CLASSPATH.
    — Ben

  10. I have a requirement that the pdf maybe multiple pages and am stumped. The data will be pulled via a query if the record count is over x, I need to create additional pages using the same pdf template something like # of # pages. Any ideas?

  11. Mike, you want to craete PDF files using CFQUERY output? Then I think you may want CFDOCUMENT, not this tag. Unless I am misunderstanding you.
    — Ben

  12. Ben,
    It seems that I have an issue populating PDFs that contain a DataConnection to an embedded XML Schema. The PDF’s I create in Designer are created with and XML Schema and fields are then bound. The SetPDFFormFields function does not work on these forms, however if I create an InputXML with the proper xml element naming instead of "Root" etc. and set the PDFData argument manually it works.
    Here is a simple procedure to replicate the issue.
    1. Open Designer & Create New Blank Document
    2. Select Data View & Create New Data Connection Type XML Schema, browse to Purchase Order.xsd (provided in the samples installation directory of designer) and embed MXL Data.
    3. Right Click DataConnection and select Generate Fields.
    4. Save As Purchase Order.pdf
    The resulting Purchase Order.pdf does not populate properly. Deleting the DataConnection and saving the document resolves the issue.
    Although this is not an issue for me since I am actually creating the XML instead of using Form.Fields, thought you might be interested in my findings.
    Allen Levine

  13. Ben-
    Very nice blog. Has there been any consideration to add functionality like stamping, merging, and stitching to the CFPDF tag? Is there a way to do this using ColdFusion currently?
    Those features would add tremendous flexibility when extracting data and generating new PDF docs on the fly. I’d love to be able to, without too much trouble, stitch two PDFs together – one PDF that takes in data and one that is a PDF graphical template(perfect for vector graphics) . If you want the graphics to be different, you could just stitch it with another template, rather than have to create a whole new PDF. I know of some plugins, like ActivePDF that can do this, but they run on VB or .NET… not so helpful for a Flasher who is now a CFer.
    Jeff

  14. A software for vginfosys does the job of Pdf form data extraction and convertion of the same to XML and if required, also saves to required database.

  15. A software from vginfosys.com does the job of Pdf form data extraction and convertion of the same to XML (and if required, also saves to required database).

  16. Is it possible to generate an encrypted PDF file using cf_pdfform? I’ve read that it’s possible to encrypt a PDF file using something like:
    Doc.Encrypt "", Request("Pwd"), 128
    Thank you.
    Matt

  17. I’m having the hardest time trying to this cfdocument tag to print multiple pages. Exactly what Mike was talking about above. It seems I can only "scale" the full size doc down to one page. That’s tough to read when a report is five pages.
    Any thought/ideas?

  18. I’m using this tag for several PDFs on a single site; all are working fine except for one. That makes me think it’s something in the PDF file itself, but I’m looking for a little confirmation.
    Here’s the error I’m seeing:
    — ERROR BEGINS HERE —
    The system has attempted to use an undefined value, which usually indicates a programming error, either in your code or some system code.
    Null Pointers are another name for undefined values.
    The error occurred in D:CFusionMX7CustomTagspdfform.cfm: line 37
    Called from D:CFusionMX7CustomTagspdfform.cfm: line 397
    Called from D:CFusionMX7CustomTagspdfform.cfm: line 354
    Called from D:CFusionMX7CustomTagspdfform.cfm: line 1
    Called from applications_formsloan_liner_generatePDF.cfm: line 18
    35 :
    36 : // Perform actual import
    37 : PDFdoc.importFormData(byteArrayIS);
    38 :
    39 : //Call the PDFDocument object’s save method
    — ERROR ENDS HERE —
    I don’t know if this error is indicative of *data* I’m sending in, or *fields* I’m sending in, etc. I’ve gone through the list of PDF form fields and am pretty sure I’m sending in all of the fields spelled correctly.
    I’d appreciate any advice or help. Thank you.
    Matt

  19. Hey guys, is there any way to force a cache delete of a pdf file out of the browser. I’m having trouble when I do a dynamic fill of a pdf, I then go back and make some changes to the data, fill that pdf again and the old data is there. If I open the pdf with the acrobat that is seperate from the browser it shows the data. It seems to be a cache problem. Any ideas?

  20. Matt’s error sounds like an error I’m getting on a custom tag — if you create a custom tag and then remove it or rename it, you get the error: "The system has attempted to use an undefined value, which usually indicates a programming error, either in your code or some system code." I haven’t found a solution yet.

  21. Actually, we did just find a solution to the "undefined value" error. If we send in a variable with no value, we’d get the error … if we sent in the same variable with a space, it works fine. So, we just add a space to the end of each value string and the whole app works fine.

  22. The tag has been working like a charm for me. I use it to pre-fill a 3-page form document and performance seems good. However, since using the tag, I have noticed that the client needs Acrobat Reader 7.x and that form fields show up as empty in earlier versions of Acrobat as well as in Preview on Mac OS X.
    The PDF was prepared with Designers and saved as a 6.x compatible format. Has anyone else run into this problem?

  23. Great new tag! Can’t wait for Scorpio to be released. Works great for dynamic form-based PDFs.
    Can XPAAJ handle inline dynamic text replacement on a PDF or XDP? All the CF/java examples I have seen demonstrate form field replacement. I am new to LiveCycle Designer so I may be missing something.
    Example:
    PDF Input: Your balance as of #due_dt# is $#amt_due#.
    PDF Output: Your balance as of 10/16/2006 is $1,234.56.
    I can resolve dynamic text using the CF replace function on a XDP file. But then I can’t figure out how to render to PDF.
    Can XPAAJ convert XDP to PDF?

  24. Kari:
    Preview on the Mac doesn’t support this type of PDF document. I think it should work with Acrobat 6, but I may be mistaken there.
    Greg:
    XPAAJ cannot convert XDP to PDF, you’ll need Adobe LiveCycle Forms for that. And I don’t believe that dynamic text replacement is possible. You could do that with a text element and a few nicely placed text fields, but the spacing may not be perfect every time.
    Mike

  25. Mike thanks for the info.
    Ben Forta’s CFMX7 web application contstruction kit book has an excellent chapter on dynamic text replacement. Chapter 33(Generating Non-HTML Content). Nate Weiss demonstrates how ColdFusion can generate and display a dynamic memo as an RTF document. I was hoping to do the same with XPAAJ and XDP/PDF.
    <cfset thisFolder = getDirectoryFromPath(getCurrentTemplatePath())>
    <cfset templatePath = thisFolder & "DocTemplate.rtf">
    <cffile action="read" file="#templatePath#" variable="rtf">
    <!— Replace "placeholders" with specific information —>
    <cfset todaysDate = dateFormat(Now(), "dddd, mmmm d, yyyy")>
    <cfset rtf = replace(rtf, "%CurrentDate%", todaysDate,"ALL")>
    <cfset rtf = replace(rtf, "%FreePrize%", sevPackage,"ALL")>

    <cfheader name="Content-Disposition" value="filename=RetireMemo.doc">
    <cfcontent type="application/msword"><cfoutput>#rtf#</cfoutput>
    Ben, both of your ColdFusion books (CFMX7 web app and adv app dev) are amazing. I have never regretted upgrading my Allaire version 4.0 books with the latest editions. They are all well-worn.

  26. Hello all,
    I’m still having the same problem as before. I can’t seem to clear the old pdf out of the cache. Here was my original post.
    Hey guys, is there any way to force a cache delete of a pdf file out of the browser. I’m having trouble when I do a dynamic fill of a pdf, I then go back and make some changes to the data, fill that pdf again and the old data is there. If I open the pdf with the acrobat that is seperate from the browser it shows the data. It seems to be a cache problem. Any ideas?

  27. I am getting the following message with ColdFusion MX 6.1.
    The argument XMLDATA passed to function SetPDFFormFields() is not of type xml.
    Any ideas

  28. Very nice blog,
    but I got a problem with text being truncated, for example if I try to fill the form fields with a string that contains extended characters like "Vous faites partie du Réseau Commercial" I end up with "Vous faites partie du R".
    Any thought/ideas why this is happening?
    Thanks

  29. I solved my inline text replacement question. In Designer you can insert floating fields into a text field. It would be nice to have the floating field as a standard library item (instead of on the Insert menu). I am sure their is a technical reason for this placement. Great custom tag.
    When will CF8 be in beta? Are their any books/manuals on Designer and LiveCycle products? The online help is OK, but nothing like training from the source books.

  30. I have a PDF file that was created from a Visio form. Can this be used to pass in a text string and have the PDF open and highlight that text string that was passed in?

  31. Dan, I have no idea what Visio generates. But if it is a PDF form thern you should indeed be able to use this to insert text.
    Greg, mid-2007. And there is far greater PDF integration planned.
    Maxime, no idea. I am passing the strings through as is, and am not parsing them at all. But I can ask aroundd.
    — Ben

  32. We finally "solved" my problem with the text being truncated. After trying everything we could think of, we just tried creating a new PDF form with Designer, and it worked. It must be something we did wrong the first time we created the pdf, like having the wrong locales. I will try to find out exactly what is was and keep you inform.
    Sorry.

  33. Ben – is it within the realm of the conceivable that Scorpio will be able to dynamically generate form fields that will work with <cfpdfform>?
    Regards,

    Jon

  34. FYI – CF_PDFForm works great! Ben did not mention to put XPAAG.jar in C:/CFusionMX7/lib. Also:
    (1) CF_PDFForm Parameter Name (i.e., PDF Field Name) can not contain "." and possibly some other characters.
    (2) Don’t waste time with CFREPORT. You will just consume endless hours tediously programming and beating your head against the Report Builder layout interface. Most of us just want to use existing PDFs and pass data to the fields. Consecutively numbering names of existing PDF fields is a who lot easier than creating temporary queries and wrestling with CFREPORT and Report Builder. Just loop out your query to produce CF_PDFForm parameters from list, table, array, or struct.

  35. OH YES – Passing numeric parameters to PDF fields in calculated columns does not seem to work correctly. Although the value is inserted into the field, it is not applied to the calculation … even when a new value is manually typed in ?

  36. Can’t speak to the issue of how many of us want to use PDF forms authored externally vs. dynamically by CF, but I can say CFREPORT has been good to us – still got some quirks (ie losing objects in bands); so do other reporting tools. However, our organization would get major mileage by building forms on the fly.

Leave a Reply