I need to make pre-populated PDF/XFA forms read-only (as in no inputs, such as text, checkboxes, radio buttons etc. can have their values changed).
For regular AcroForms PDFs and static XFA forms, I can accomplish this by calling setFormFlattening(true)
on the PdfStamper instance. For dynamic XFA forms, I have to set an access
attribute of the XDP's field
node to be readOnly
.
The problem is, how do I detect if a form is dynamic XFA? isXfaPresent
doesn't differentiate between static or dynamic XFA forms, so isn't useful.
iText is free as in free speech, not free as in free beer. Read http://lowagie.com/bumodels for more info about the business models we've tried in order to avoid switching from the MPL/LGPL to the AGPL.
Q1: making dynamic XFA forms read-only
That's a no-brainer with the most recent version of iText, but not supported in the obsolete version you're using. Please read http://lowagie.com/itext2 to find out why you shouldn't use iText 4.2.0 (which as far as I know isn't even an official release; and I know, because I'm responsible for every single iText release). Maybe you're talking about iTextSharp.
Q2: flattening dynamic XFA forms
If you want to flatten a dynamic XFA form, you have two options: either use Adobe LiveCycle ES (which will cost you an arm and a leg), or use iText's XFA Worker (which is a much less expensive closed source product built on top of the F/OSS iText). Given the cost and the number of man hours that went into this product, I don't think you'll find a solution that is free as in free beer. I for one don't know of any such product.
Q3: how to find out if an XFA form is dynamic
This is explained in my book, "iText in Action - Second Edition." You already have half of the solution. Condition 1: isXfaPresent()
needs to return true
. Condition 2: getFields()
needs to have an empty key set. See the method readFieldnames()
in this example.
To add to Bruno's answer and to provide C# example code:
PdfReader reader = new PdfReader(filePath);
XfaForm xfa = new XfaForm(reader);
//Check if PDF file contains Dynamic XFA data
if (xfa != null && xfa.XfaPresent && xfa.Reader.AcroFields.Fields.Keys.Count == 0)
{
MessageBox.Show("This PDF contains Dynamic XFA data.");
}