About IText AcroFields - itext

I am trying to generate pdf from template using iText. I've set value in AcroFields. when I opening output file, there is nothing on it.Is there anyone who had same problem before? .
FileOutputStream fos = new FileOutputStream(destPath);
PdfReader reader = new PdfReader(templatePath);
PdfStamper stamp = new PdfStamper(reader, fos);
AcroFields form = stamp.getAcroFields();
form.setField("parttype", "1dafd");
stamp.setFormFlattening(true);
stamp.close();
fos.flush();
fos.close();

Related

Field validation in editable pdf while filling data

I have editable pdf with fields name, roll number , DOB and city, I want to validate the fields like, for example when I enter the value in roll number field, if name is empty then it should alert "name is empty" and similar to roll number and DOB and city.
DOB - Need to validate mm/dd/yyyy format.
I am able to get fields and values using below iTextSharp code, but how can validate and and show alert to user.
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(filename);
using (MemoryStream outputStream = new MemoryStream())
{
//PdfStamper stamper = new PdfStamper(reader, );
using (PdfStamper stamper = new PdfStamper(reader, outputStream, '\0', true))
{
PdfWriter writer = stamper.Writer;
AcroFields acroFields = reader.AcroFields;
AcroFields.Item dateField = acroFields.GetFieldItem("D");
iTextSharp.text.pdf.PdfAction pdfAction = iTextSharp.text.pdf.PdfAction.JavaScript("app.alert('hello');", writer);
iTextSharp.text.pdf.PdfDictionary widgetRefDict = (iTextSharp.text.pdf.PdfDictionary)iTextSharp.text.pdf.PdfReader.GetPdfObject(dateField.GetWidgetRef(0));
iTextSharp.text.pdf.PdfDictionary actionDict = widgetRefDict.GetAsDict(iTextSharp.text.pdf.PdfName.AA);
if (actionDict == null)
{
actionDict = new iTextSharp.text.pdf.PdfDictionary();
// add the newly created action dict
widgetRefDict.Put(iTextSharp.text.pdf.PdfName.AA, actionDict);
}
actionDict.Put(iTextSharp.text.pdf.PdfName.V, pdfAction);
stamper.Close();
reader.Close();
}
byte[] content = outputStream.ToArray();
// Write out PDF from memory stream.
using (FileStream fs = File.Create("d:\\Page1-output.pdf"))
{
fs.Write(content, 0, (int)content.Length);
}
}

How to use itext to submit PDF Form

After reading many stackoverflow and tried many solutions I'm stuck with this:
I am receiving a PDF that I cannot change and need to automatically process it.
The PDF is a PDF form with 2 fields and submit button.
The following code is the closes I came to what I need to do:
public static final String SRC = "C:\\Dev\\test.pdf";
public static final String DEST = "C:\\Dev\\test_result.pdf";
public static final String DATA = "C:\\Dev\\data.xml";
File file = new File(DEST);
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(DATA));
This gives a null pointer:
Exception in thread "main" java.lang.NullPointerException
at com.itextpdf.text.pdf.XfaForm.fillXfaForm(XfaForm.java:1168)
at com.itextpdf.text.pdf.XfaForm.fillXfaForm(XfaForm.java:1146)
at com.itextpdf.text.pdf.XfaForm.fillXfaForm(XfaForm.java:1134)
at com.itextpdf.text.pdf.XfaForm.fillXfaForm(XfaForm.java:1131)
I can get and set the fields on the form with this code:
AcroFields fields = reader.getAcroFields();
fields.setField("pdfForm.loginUser", "myemail#domain.com");
fields.setField("pdfForm.loginPass", "mypassword");
How do I convert the Acrofields to XfaForm?

docx with track change producing incorrect output in Apache Tika

I am parsing docx files using apache tika.
AutoDetectParser parser = new AutoDetectParser();
ContentHandler contentHandler = new BodyContentHandler();
inputStream = new BufferedInputStream(new FileInputStream(inputFileName));
Metadata metadata = new Metadata();
OfficeParserConfig officeParserConfig = new OfficeParserConfig();
officeParserConfig.setIncludeDeletedContent(false);
parseContext.set(OfficeParserConfig.class, officeParserConfig);
parser.parse(inputStream, contentHandler, metadata, parseContext);
System.out.println(contentHandler.toString());
When I am sending track_revised docx file it's adding all the text deleted with the actual text and inserted text. Is there a way to tell parser to exclude the deleted text?
I did figure it out
AutoDetectParser parser = new AutoDetectParser();
ContentHandler contentHandler = new BodyContentHandler();
inputStream = new BufferedInputStream(new FileInputStream(inputFileName));
Metadata metadata = new Metadata();
ParseContext parseContext = new ParseContext();
OfficeParserConfig officeParserConfig = new OfficeParserConfig();
officeParserConfig.setUseSAXDocxExtractor(true);
officeParserConfig.setIncludeDeletedContent(false);
parseContext.set(OfficeParserConfig.class, officeParserConfig);
parser.parse(inputStream, contentHandler, metadata, parseContext);
System.out.println(contentHandler.toString());

How to fill XFA from using iText so it is Foxit Reader comptible

I used examples available on web to create an application that is able to get xml structure of XFA form and then set it back filled. Important code looks like this:
public void readData(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);
Node node = xfa.getDatasetsNode();
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
if ("data".equals(list.item(i).getLocalName())) {
node = list.item(i);
break;
}
}
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.transform(new DOMSource(node), new StreamResult(os));
reader.close();
}
public void fillPdfWithXmlData(String src, String xml, String dest)
throws IOException, DocumentException {
PdfReader.unethicalreading = true;
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest), '\0', true);
AcroFields form = stamper.getAcroFields();
XfaForm xfa = form.getXfa();
xfa.fillXfaForm(new FileInputStream(xml));
stamper.close();
reader.close();
}
When I use it to fill this form: http://www.vzp.cz/uploads/document/tiskopisy-pro-zamestnavatele-hromadne-oznameni-zamestnavatele-verze-2-pdf-56-kb.pdf it works fine and I can see the filled form in Acrobat Reader. However, if I open the document in Foxit Reader I see a blank form (tested in latest version and 5.x version).
I tried to play a little bit with it and got these XfaForm(...).getDomDocument() data:
Filled by Acrobat Reader: http://pastebin.com/kXKyh9EM
Filled by Foxit Reader: http://pastebin.com/tiZ7EmfE
Filled by iText: http://pastebin.com/tTKLMERC
Filled by Foxit Reader after a fill by iText: http://pastebin.com/Uuq0jS4b
The field which was filled is . Is it possible to use iText in a way that it works even with Foxit Reader (and the XFA signature stays?)
In your Filled by iText example there's a superfluous <xfa:data> element:
<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
<xfa:data>
<xfa:data>
<HOZ>
<!-- rest of your data here -->
</HOZ>
</xfa:data>
</xfa:data>
<!-- data description -->
</xfa:datasets>
This is because the fillXfaForm() method of XfaForm expects the XML data without <xfa:data> as the root element. So your XML data should just look like:
<HOZ>
<!-- rest of your data here -->
</HOZ>
I see that your readData() method that extract the existing form data including the <xfa:data> element:
<xfa:data>
<HOZ>
<!-- rest of your data here -->
</HOZ>
</xfa:data>
Stripping the outer element should fix your problem. For example:
XfaForm xfa = new XfaForm(reader);
Node node = xfa.getDatasetsNode();
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
if ("data".equals(list.item(i).getLocalName())) {
node = list.item(i);
break;
}
}
// strip <xfa:data>
node = node.getFirstChild();
// Transformer code here

itextsharp 5.4.4 CopyAcroForm no longer there

In version 5.4.2 of itextsharp I was able to use: (fragment in VB)
Dim pdfWriter As iTextSharp.text.pdf.PdfCopy
pdfwriter = New iTextSharp.text.pdf.PdfCopy(outputPDFDocument, New FileStream(destfname, FileMode.Create))
pdfWriter.CopyAcroForm(reader)
to copy a form from one document to another.
In 5.4.4 CopyAcroForm is no longer there under PdfCopy or anywhere else - what is the alternative?
Please read the release notes for iText 5.4.4. It is now possible to use PdfCopy to merge PDFs containing AcroForm forms by using the addDocument() method. This method is much better than the copyAcroForm() method as it also preserves the structured tree root. This is important if your forms are made accessible (cf Section 508 or the PDF/UA standard).
AddDocument() method is cool. Here is my code that read and merge multiple PDFs from SQL server in asp.net . document.Close() is required to flush the content to memory stream.
enter code here
Document document = new Document();
MemoryStream output = new MemoryStream();
PdfCopy writer = new PdfCopy(document, output); // Initialize pdf writer
writer.SetMergeFields();
document.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
PdfReader reader = new PdfReader((Byte[])dr["ImageFile"]);
writer.AddDocument(reader);
}
dr.Close();
document.Close();
It looks like you also need to call .SetMergeFields() or it won't work:
reader = new PdfReader(path);
using (var document = new Document(reader.GetPageSizeWithRotation(1))) {
using (var outputStream = new FileStream(...)) {
using (var writer = new PdfCopy(document, outputStream)) {
writer.SetMergeFields();
document.Open();
//all pages:
writer.AddDocument(reader);
//Particular Pages:
//writer.AddDocument(reader, new List<int> { pageNumber });
}
}
}