Ok, so in my previous post on PDF forms with CF8, I tried really hard to figure why I couldn’t simply create a form in Acrobat, fill it out using CF, and make what I filled out like the other static text, so that the user can’t change the form.
Turns out CF8 CANNOT do this natively. Its a simple use case. In our case, we are creating nice certificates for our users when they complete and pass an exam.
To make things worse, the CF8 docs make it seem like its doable. With words like “flatten” make you think everything’s going to be all right. But it aint. Flattening obliterates all the fields, removing them all together, while the documentation says : removes interactivity. Hell yeah, its no longer interactive!
But there is hope. With a little iText (dont be scared, its simple) and Javaloader magic, I was able to get it to work.
Let’s run through the code, shall we?
Download Mark Mandel’s JavaLoader from RiaForge and iText (latest version).
Follow the code below. And that is it!
// First we load the latest iText JAR using JavaLoader. Adjust paths as necessary. paths = arrayNew(1); // Latest iText JAR paths = expandPath("iText-2.1.3.jar"); // Use Mark JL loader = createObject("component", "javaloader.JavaLoader").init( paths ); // I've already named the blank cert form and the new populated cert previous. Adjust as you see fit. newFile=expandPath(local.newPDFFile); pdfFile=expandPath(local.PDFFile); // Then some iText Magic fos=createObject("java","java.io.FileOutputStream").init(newFile); reader = loader.create("com.lowagie.text.pdf.PdfReader").init(pdfFile); pdfStamper = loader.create("com.lowagie.text.pdf.PdfStamper").init(reader, fos); // add some data to the form pdfForm=pdfStamper.getAcroFields(); // We have 3 fields, first_last, orgCity_orgState, and date // Here we are using the form scope, adjust as necessary. pdfForm.setField("First_Last", trim(form.First_Last)); pdfForm.setField("OrgCity_OrgState", trim(form.OrgCity_OrgState)); pdfForm.setField("Date", trim(form.Date)); // Lets do a REAL flatten. pdfStamper.setFormFlattening(true); // Close out! pdfStamper.close(); reader.close();
Last, serve up the file!
<cfcontent type="application/pdf" reset="true" file="#ExpandPath(local.newPDFFile)#" >