I am currently using Excel to populate a PDF file with form fields. It all works but it exports it as a .xfdf. Does anyone know how I can save it as a pdf instead?
XFDF is the XML flavor of FDF. FDF stands for Forms Data Format. It is a file format to store data without the actual content of a PDF. FDF uses PDF syntax to store this data. XFDF uses XML.
You can't "convert" an FDF or XFDF file to PDF because there is too much information missing. You can import an (X)FDF file into a PDF that has corresponding AcroForm fields.
Please take a look at the ImportXFDF example. For that example, I wrote a simple XFDF file: data.xfdf:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<fields>
<field name="Submitted by"><value>Santaaimonce</value></field>
<field name="Job name"><value>Developer</value></field>
<field name="Shipping address"><value>Alphabet Street
Minneapolis
Minnesota</value></field>
<field name="Special instructions"><value>Use iText to fill out interactive form using data stored in XFDF file.
If you are a C# developer, use iTextSharp.</value></field>
</fields>
<f href="Requisition_Fillable.pdf"/>
</xfdf>
This information is not sufficient to create a PDF, but as you can see, there is a reference to a template PDF file: Requisition_Fillable.pdf.
If you put data.xfdf
and Requisition_Fillable.pdf
in the same directory and you open data.xfdf
, you will see the following message:
Adobe Reader opened the XFDF file, found the reference to the PDF template, opened the template and now asks you if you want to import the data. If you click on the Options button and you allow the import, you will get this result:
The problem you are experiencing is simple: you don't have the file Requisition_Fillable.pdf anywhere. You may also want to avoid that people are able to change the data that is filled in.
You can solve this by merging the XFDF file and its template programmatically:
protected void fillXfdf(String SRC, String XFDF, String DEST) throws IOException, DocumentException {
// We receive the XML bytes
XfdfReader xfdf = new XfdfReader(new FileInputStream(XFDF));
// We get the corresponding form
PdfReader reader = new PdfReader(SRC);
// We create an OutputStream for the new PDF
FileOutputStream baos = new FileOutputStream(DEST);
// Now we create the PDF
PdfStamper stamper = new PdfStamper(reader, baos);
// We alter the fields of the existing PDF
AcroFields fields = stamper.getAcroFields();
fields.setFields(xfdf);
// take away all interactivity
stamper.setFormFlattening(true);
// close the stamper
stamper.close();
reader.close();
}
Mind the following line:
stamper.setFormFlattening(true);
This will flatten the form: the fields will no longer be fields, they will just be like any other content. You end up with a regular PDF: xfdf_merged.pdf
Obviously this will only work if the form (in this case Requisition_Fillable.pdf
) corresponds with the data in the XFDF stream. For instance: my template will work with your data for the fields "Submitted by"
and "Shipping address"
. It won't work for the fields "Job Name"
and "Special Instructions"
, because those fields don't exist in my template. In my template those fields are named "Job name"
and "Special instructions"
; do you see the lower cases instead of the upper case?
If you want to use my template, you'll have to change those two field names, either in your XFDF file or in the PDF template. Also: my example is written in Java. As you are working in VB, you'll have to use the .NET version of iText, which is called iTextSharp. An experienced VBA developer shouldn't have any problem porting my example from Java to VB. Just think of the Java as if it were pseudo-code.
DISCLAIMER: the above example requires iText. I am the CEO of the iText Group and the example was taken from my book "iText in Action - Second Edition".