Using iText (iTextSharp) to populate XFA form fields in PDF? - c#

I need to populate XFA form fields in a PDF (created with Adobe LiveCycle Designer). We're attempting to use iText (actually iTextSharp with C#) to parse the PDF, populate the XFA fields and then save the modified PDF back out.
All the examples I can find with iText (very few iTextSharp examples) talk about modifying AcroForm fields. This PDF does NOT have AcroForm fields and uses XFA only.
Pointers to any non-standard resources would be helpful (I've already done the requisite Googling on the topic and haven't found anything useful).
Code examples here would be awesome from anyone who has actually done what I'm trying to do.

If you can get a data packet into the PDF, the XFA runtime in Acrobat would populate those fields with the data in the data packet.
If you want to see what one of these looks like, create a form in LiveCycle Designer (comes with Acrobat Pro), add some fields to it, and save it as a dynamic PDF. Open the form in Acrobat and type some values into the fields and save it.
Open the PDF with a tool that lets you peer at the PDF data and you'll find /Catalog/AcroForm/XFA a stream that has an <xfa:datasets> packet with the values you typed. That's what you'll need to create yourself and insert into the PDF.
The XDP spec includes a description of the data packet and the merge algorithm. You can find it here:
http://partners.adobe.com/public/developer/xml/index_arch.html
Alternately, you buy the LiveCycle server from Adobe which lets you do all this programmatically in a number of ways including through web service calls.

using (FileStream existingPdf = new FileStream("existing.pdf", FileMode.Open))
using (FileStream sourceXml = new FileStream("source.xml", FileMode.Open))
using (FileStream newPdf = new FileStream("new.pdf", FileMode.Create))
{
// Open existing PDF
PdfReader pdfReader = new PdfReader(existingPdf);
// PdfStamper, which will create
PdfStamper stamper = new PdfStamper(pdfReader, newPdf);
stamper.AcroFields.Xfa.FillXfaForm(sourceXml);
stamper.Close();
pdfReader.Close();
}

iTextSharp can work with XFA. To remove all doubts, please take a look at sample on iText website:
http://itextpdf.com/examples/iia.php?id=165

I have the same issue and I think I found the solution. I am using Powershell to inspect the pdf object.
Load the iTextSharp DLL.
Add-Type -Path "C:\Users\micah\Desktop\itextsharp.dll"
Load the PDF into a variable:
$PDF = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList "C:\Users\micah\Desktop\test.pdf"
Inspect this object:
$PDF.AcroFields.XFA.DomDocument.XDP.DataSets.Data.TopMostSubForm | Get-Member
What you SHOULD see, is that all your fields on your PDF are in this object as a property.
You can get a quick view of all your fields like this:
$PDF.AcroFields.XFA.DomDocument.XDP.DataSets.Data.TopMostSubForm | Select-Object -Property "*"
That should be the magic ticket. This location is both fields from the original form AND the XFA portion of the form.

It says that in the book because itext does not do this. Can you convert your PDF?

Related

iTextSharp, add barcode to page 1 after generating document

I am using iTextSharp (5.5.5.90) to generate PDF files. I am using paragraphs and importing pages from readers and such. Here is how I create my document, from there I just append what I need:
FileStream fs = new FileStream("filename.pdf", FileMode.Create, FileAccess.Write, FileShare.None);
Document doc = new Document(new Rectangle(PageSize.LETTER), 58, 58, 100, 50);
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
Once the file is created, I add paragraphs like this:
doc.Add(new Paragraph("Paragraph text"));
And import pages from readers like this:
writer.DirectContent.AddTemplate(writer.GetImportedPage(reader, page), 0, 0);
My question is how would I go back to page one after generating the entire document and add an element to page one? I will be adding a barcode (I know how to add barcodes, tables and such where I want them on the current page), but I don't know how to "go back" to page one to add an element.
Here is the full code, but you won't be able to compile it because of dependencies. Also, don't get caught up in the details of the full code, as this is a large project to create dynamically generated documents. https://pastebin.com/kABi7fzW
I can't attest as to the exactly calls to iTextSharp's as we approached our documentation quite differently; open a Word template, at the data as DataTables, etc., do a MailMerge, close and reopen and save as PDF. Sounds more involved but doesn't require the granular level of detail you're doing of creating the document paragraph by paragraph but it does allow the document generator to worry about content and not style placement (handled via Word, manually and external to the application).
From experience with iTextSharp, you'll have a lot of trouble trying to float an element on top of a section to insert the barcode. The document generation tool has an annoying tendency to not quite work in this scenario. We endured many weeks of back and forth with iTextSharp support and a version upgrade and still couldn't get it to behave properly in all scenarios.
As discussed in the comments and given how you've already written your code (I doubt you'll scrap all that code and start with a MailMerge unless you really, really have to), you'll need to insert a placeholder block that you can locate via iTextSharp's PdfBuilder api. I'd imagine that setting a bookmark location would likely be the easiest way.
If it's possible (preferable?) to have the barcode on a page of its own, then you already have the code needed to do this (circa line 324 in your pastebin link) with;
// create doc...
// reopen doc and get page count
doc.NewPage();
// add barcode with page count + 1
// save

How to use Pdfsharp to read form fields of pdf file in c#

I want to use Pdfsharp to perform some operation's on pdf file as it is free. But I don't know how to use it.
I just try something like this,
string pdfTemplate = #"C:\Users\Tudip\Downloads\State Tax Forms\State Tax Forms\Louisiana L-4 (1).pdf";
var doc = PdfReader.Open(pdfTemplate);
// Code for Read pdf fields
// Code for insert data in pdf fields
Download the source code for version 1.32 and check out the sample in the ReadFormFields folder.
https://sourceforge.net/projects/pdfsharp/files/pdfsharp/PDFsharp%201.32/
Form fields should also work with version 1.50 of PDFsharp.

Disable extended features with iTextSharp

I have a PDF template with a form with the Extended features enabled. After filling in the fields of this form using iTextSharp, a user with acrobat reader gets the error message:
This document enabled extended features in Adobe Reader. The document has
been changed since it was created and use of extended features is no longer
available. Please contact the author for the original version of this
document.
I googled a bit but all the posts talk about "enabling" extended features, however, I want the form fields to remain disabled and extended features turned off
Here a sample code which I am using:
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
// Open existing PDF
var pdfReader = new PdfReader(existingFileStream);
// PdfStamper, which will create
var stamper = new PdfStamper(pdfReader, newFileStream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
if (fieldKey.Equals("Retailer Name"))
form.SetField(fieldKey, retailerName);
}
// “Flatten” the form so it wont be editable/usable anymore
stamper.FormFlattening = true;
stamper.Close();
pdfReader.Close();
}
The links here are dead as the iTextPdf web site has been completely revamped. But the answer can be understood without those links, too.
The iText Keyword: Reader enabled PDFs points to the following information:
Submitted by Bruno Lowagie on Fri, 12/31/2010 - 16:37
After filling out my form, my PDF shows the following message: This document enabled extended features in Adobe Reader. The document has been changed since it was created and use of extended features is no longer available. Please contact the author for the original version of this document. How do I avoid this message?
The creator of the form made the document Reader enabled. Reader enabling can only be done using Adobe software. You can avoid this message in two ways:
Remove the usage rights. This will result in a form that is no longer Reader enabled. For instance: if the creator of the document allowed that the filled out form could be saved locally, this will no longer be possible after removing the usage rights.
Fill out the form in append mode. This will result in a bigger file size, but Reader enabling will be preserved.
It also points to the sample ReaderEnabledForm.java (the C#/iTextSharp equivalent of which is ReaderEnabledForm.cs) which shows how to do either.
In your case this amounts to calling
pdfReader.RemoveUsageRights();
right after creating the PdfReader and before creating the PdfStamper.
/**
* Removes any usage rights that this PDF may have. Only Adobe can grant usage rights
* and any PDF modification with iText will invalidate them. Invalidated usage rights may
* confuse Acrobat and it's advisabe to remove them altogether.
*/
public void RemoveUsageRights()
Fill out the form in append mode by using the PdfStamper constractor overload
// PdfStamper, which will create
var stamper = new PdfStamper(pdfReader, fileStream, '\0', true);

Fill PDF Form with Itextsharp

I am trying to fill up a form with ITextsharp, and trying out the following code to get all the fields in the pdf:
string pdfTemplate = #"c:\Temp\questionnaire.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
StringBuilder sb = new StringBuilder();
foreach (var de in pdfReader.AcroFields.Fields)
{
sb.Append(de.Key.ToString() + Environment.NewLine);
}
But the foreach loop is always null count. Do I need to do something to file itself as I have tried the example from here and it works fine... this is an example of pdf I am trying to fill
any ideas?
Edit ::
As it turned out, the PDF "form" to fill in actually wasn't a form (in PDF terms) at all. Thus, your have two choices:
You add the text to the page contents directly using hardcoded or configured "field" positions and dimensions as described by #tschmit007 in comments to his answer.
You add actual PDF form fields to your PDF to generate a true PDF form which you take as template to fill in later.
You can add actual form fields either using some graphical tool allowing that, e.g. Adobe Acrobat, or you can use iText(Sharp). Have a look at chapter 8 of iText in Action — 2nd Edition and the samples available here for Java and here for .Net.
Those samples mostly add form fields to newly generated PDF documents. You can virtually use the same code, though, for adding form fields to a PdfStamper which exposes its inner PdfWriter using stamper.getWriter() in Java and the stamper.Writer in C#. Instead of writer.addAnnotation(field) you have to use stamper.addAnnotation(field, page), though.
try:
using (FileStream outFile = new FileStream("result.pdf", FileMode.Create)) {
PdfReader pdfReader = new PdfReader("file.pdf");
PdfStamper pdfStamper = new PdfStamper(pdfReader, outFile);
AcroFields fields = pdfStamper.AcroFields;
//rest of the code here
//fields.SetField("n°1", "value");
//...
pdfStamper.Close();
pdfReader.Close();
}

ITextSharp Multiple Page PDF from several templates

I have a requirement to generate a PDF from multiple different (Unknown page Sized PDF's)
Create a cover sheet from a template and write the text onto it.
Pull a PDF (Unknown page size) and append to the above 3) Repeat
until all required PDF's are attached
Step 1 is not a problem and this is working, so I have a a cover sheet PDF generated. I now need a way to append the additional PDF's as above. How can we achieve this using ITextSharp?
If you are trying to concatenate multiple PDF files into one you may take a look at the following post.
I found a simple way to do this, I found something called PDFCopy in ITextSharp
void MergePdfStreams(List<Stream> Source, Stream Dest)
{
var copy = new PdfCopyFields(Dest);
foreach (Stream source in Source)
{
var reader = new PdfReader(source);
copy.AddDocument(reader);
}
copy.Close();
}
Source : Is there a straight forward way to append one PDF doc to another using iTextSharp?

Categories

Resources