Web Software Architecture and Engineering – Life on the Bleeding Edge

Ok, I’m stumped.. Can someone help me out?
Here is the scenario: We have a simple certificate pdf. Its has fields for name, org name, and date. Once the user finishes and passes a test, we are to output this certificate in pdf format with the fields filled out.
How far I got: I am easily able to fill out the pdf. However, the fields are writable, so I need a way to lock them, so the user can’t simply start typing names in the name field and print certificates to his/her heart’s desire. I thought to remove the “AllowFillIn” permission, but that completely removes the fields, and we end up with the empty certificate. The same goes for “flatten.”
Am I missing something? How can I get a nice certificate that is only printable?

Advertisements

Comments on: "Help Needed – Populating PDF Forms with CF8" (15)

  1. using the iText lib that comes with cf you can partially flatten a form so that only the fields you want are turned into painted text or a better solution would be turn those fields into read-only ones.

    check out the PdfStamper & AcroFields classes. let me know if you need a code snippet.

  2. Paul,

    Really? All that work? πŸ˜€

    Well, sure, any help you can provide would rock!

    This would really help me out.

  3. Hi Sami,

    So, cfpdf’s fatten totally removes the field? – that sounds a bit buggy; the help page just specifies that “interactivity is turned off” and
    “the form fields are no longer interactive”.

    On another note, just wondering if you need some form of higher security to stop forged certificates. Once you have the PDF fields locked what’s to stop someone bringing the PDF into Illustrator (or another program), editing and printing out certificates. Could you use some form of (visual) barcoding in addition to digitally signing the PDF?

    Cheers

    David

  4. the read only approach doesn’t seem to work w/the iText version that comes w/cf. might work w/latest version (need to use mark’s javaloader). in any case have a look at this:

    newFile=expandPath(“registered.pdf”);
    pdfFile=expandPath(“simpleRegistrationForm.pdf”);
    fos=createObject(“java”,”java.io.FileOutputStream”).init(newFile);
    reader=createObject(“java”,”com.lowagie.text.pdf.PdfReader”).init(pdfFile);
    pdfStamper=createObject(“java”,”com.lowagie.text.pdf.PdfStamper”).init(reader, fos);
    // add some data to the form
    pdfForm=pdfStamper.getAcroFields();
    pdfForm.setField(“name”, “Bruno Lowagie”);
    pdfForm.setField(“address”, “Baeyensstraat 121, Sint-Amandsberg”);
    pdfForm.setField(“postal_code”, “BE-9040”);
    pdfForm.setField(“email”, “bruno@lowagie.com”);
    // lets keep bruno’s name as read only field
    pdfStamper.setFormFlattening(true);
    pdfStamper.partialFormFlattening(“name”);
    pdfStamper.close();

  5. I did a TON with CFPDF on a recent project and I can confirm there are numerous issues with populating and flattening PDF forms. After running things through Adobe support they admitted several bugs I pointed out and supposedly have put in enhancement requests for the ones I found.

    Not sure if this is helpful or not, but in my case I have to add an unknown number of addendum pages to my final PDFs because I don’t know ahead of time how many pages there will be (total number of pages is based on the data), so here are the steps I’m doing to read a PDF form pages, populate the pages with data, and combine them into a final single flattened PDF containing the data. The real kicker is that when you do a merge of PDFs, if they haven’t been flattened the data is lost.

    1. Read PDF form for the necessary page from disk and populate with data using

    2. Flatten the page using , followed by (Note that this read/write action is necessary because there’s no flatten attribute on cfpdfform).

    3. Add name of file to a list (let’s call it filesToMerge) of the final files you’re going to merge together.

    4. Repeat steps 1 – 3 for all additional pages.

    5. Merge everything with

    6. Delete all the temp files used to generate the final PDF

    Complete pain because if you could just flatten as part of all this other nonsense wouldn’t be necessary. I believe Adobe was going to put in enhancement requests for both adding flatten to as well as fixing what IMO is a bug with the merging where you lose data unless the pages have explicitly been flattened.

    Wasn’t exactly what you’re doing but figured maybe some of the ideas here would help.

  6. @David,

    Yeah, it caught me off guard. “interactivity is turned off” and “the form fields are no longer interactive” means the form is completely obliterated! Its not even hidden… I just wanted whatever I populated the form fields to “look” like the text in the cert. Simple use case.

    @Paul,

    I’ll be trying your code next. Thanks!

    @Matt,

    Thanks for long and details post and the email. You should really blog about this. Its definitely a much bigger pain that I would have liked. Seeing what you did, does help me out to see what kind of hoops I should expect to have to go through.

    @All,

    The real kicker here is that one of the features that sold management CF8 (and got them to buy 6 Enterprise licenses) was how simple it was going to be working with PDFs in CF8. Now I’ve got all sorts of expectations!

  7. @Paul,

    On CF8, seems this line gets rid of the fields.
    pdfStamper.setFormFlattening(true);

    I’m stuck…

  8. not here (also cf8, latest hotfixes, etc.). can you send me a PDF to test?

  9. @Paul,

    I sent you the form.

    Tried the latest iText with JavaLoader. It returns:

    “Partial form flattening is not supported with XFA forms.”

    Similar to what it in these forums:
    http://www.nabble.com/How-to-partial-flatten-a-XFA-Form–td17993488.html

  10. @All,

    Ok, got it to work with the latest iText I believe. Some more testing required. I think I’ll post my code.

    Basically, removed any reference to partialFormFlattening. setFormFlattening was enough with the latest iText JAR.

  11. I’ll try for a more broader post, but here is some code:

    paths = arrayNew(1);

    //Latest iText JAR
    paths[1] = expandPath(“iText-2.1.3.jar”);

    //Use Mark JL
    loader = createObject(“component”, “javaloader.JavaLoader”).init( paths );

    newFile=expandPath(local.newPDFFile);
    pdfFile=expandPath(local.PDFFile);
    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();
    pdfForm.setField(“First_Last”, trim(First_Last));
    pdfForm.setField(“OrgCity_OrgState”, trim(OrgCity_OrgState));
    pdfForm.setField(“Date”, trim(Date));

    pdfStamper.setFormFlattening(true);

    // partialFormFlattening Fails on an Acrobat Created Form?!
    //pdfStamper.partialFormFlattening(“First_Last”);

    // Close out
    pdfStamper.close();
    reader.close();

    // Serve up Cert!

  12. I had no problem doing something what you wanted.

    My scenario was:
    1.) using a blank form as template (e.g. template.pdf)
    2.) read it to memory using CFPDF action=”read”
    3.) fill the variable with CFPDFFORM
    3.) flatten it (it = pdf in memory)
    4.) save it to another PDF

    It worked for me very well. If it doesn’t work for you somehow, I’d make sure the template.pdf is a valid PDF form. Is it created using Adobe Acrobat?

  13. Henry,

    Do you have a PDF I can try? Our form was created using Acrobat indeed.

    Sami

  14. Have you tried to just leave blank the field ReadOnly from Acrobat Reader? it’s on the options window for the text field.
    As long as i know you can put the value from cf8 with cfpdfform and it would not be editable.

    Hope it works

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: