I have a local PDF form that has a specific template that never changes. I've identified the form as an XFA (xml) dynamic form since no keysets were returned. I'm trying to use itext to fill in the form with data contained in a .txt file. From my understanding I need to somehow get the data from the text file and place it properly into a .xml file so that itext can manipulate the original PDF by using the given xml.
The form has the following layout as an example:
The sample code I'm using in Eclipse compiles/runs successfully but it requires the data in the file data.xml in order to populate the empty form with field data and output the filled-in version. The thing is, for my actual project I don't have a data.xml file to use in order to populate the form properly. The raw field data is in a .txt file with each line containing data for a different field in the PDF.
EXAMPLE: Referencing the image above, my .txt file looks like this for the fields up to and including the field labelled "FOUR":
- John
- 15
- Black
- Honda
- Toyota
- Ford
- BMW
I'm confused about 2 things:
1. How do I extract the original PDF's xml structure so that I know the format to adhere to when populating it with data from the .txt file?
2. How do I get the values from the text file and insert them into the .xml structure properly?
The following code works but requires data.xml in order to fill in "incomplete.pdf". It uses the code xfa.fillXfaForm(new FileInputStream(XML)); to input the data, but I'm stuck on how to identify the structure for "XML" and how to fill it in in the first place.
Any help is appreciated, thank you very much.
Code:
package sandbox;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.XfaForm;
public class FillXFA {
public static final String SRC = "C:/Workspace/PDF/incomplete.pdf";
public static final String XML = "C:/Workspace/PDF/data.xml";
public static final String DEST = "C:/Workspace/PDF/completed.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new FillXFA().manipulatePdf(SRC, DEST);
}
public void readXfa(String src, String dest)
throws IOException, ParserConfigurationException, SAXException,
TransformerFactoryConfigurationError, TransformerException {
FileOutputStream os = new FileOutputStream(dest);
PdfReader reader = new PdfReader(src);
XfaForm xfa = new XfaForm(reader);
Document doc = xfa.getDomDocument();
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.transform(new DOMSource(doc), new StreamResult(os));
reader.close();
}
public void manipulatePdf(String src, String dest)
throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader,
new FileOutputStream(dest));
AcroFields form = stamper.getAcroFields();
XfaForm xfa = form.getXfa();
xfa.fillXfaForm(new FileInputStream(XML));
stamper.close();
reader.close();
}
}
