Reputation: 71
I have a PDF form with filled out fields. If I try to read the acrofields they are empty. But in the PDF I can change the values and save them.
private static string GetFormFieldNamesWithValues(PdfReader pdfReader)
{
return string.Join("\r\n", pdfReader.AcroFields.Fields
.Select(x => x.Key + "=" +
pdfReader.AcroFields.GetField(x.Key))
.ToArray());
}
var reader = new PdfReader((DataContext as PDFContext).Datei);
AcroFields form = reader.AcroFields;
txt.Text = GetFormFieldNamesWithValues(reader);
How to read the fields?
Upvotes: 3
Views: 8250
Reputation: 570
C# version
public void FixBrokenForm(string src, string dest)
{
PdfReader reader = new PdfReader(src);
PdfDictionary root = reader.Catalog;
PdfDictionary form = root.GetAsDict(PdfName.ACROFORM);
PdfArray fields = form.GetAsArray(PdfName.FIELDS);
PdfDictionary page;
PdfArray annots;
for (int i = 1; i <= reader.NumberOfPages; i++)
{
page = reader.GetPageN(i);
annots = page.GetAsArray(PdfName.ANNOTS);
for (int j = 0; j < annots.Size; j++)
{
fields.Add(annots.GetAsIndirectObject(j));
}
}
PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
stamper.Close();
reader.Close();
}
You will need Itextsharp to make the above code work.
Upvotes: 1
Reputation: 2066
The answers with the FixBrokenForm code are good, but don't forget to call fields.setGenerateAppearances(true) or you'll lose the fields if you call stamper.setFormFlattening(true). You can do like this:
PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
// Add these 2 lines ***************************
AcroFields acrofields = stamper.getAcroFields();
acrofields.setGenerateAppearances(true);
// *********************************************
stamper.Close();
reader.Close();
Upvotes: 0
Reputation: 71
Here is my c#-Code:
PdfReader reader = new PdfReader(src);
PdfDictionary root = reader.Catalog;
PdfDictionary form = root.GetAsDict(PdfName.ACROFORM);
PdfArray fields = form.GetAsArray(PdfName.FIELDS);
PdfDictionary page;
PdfArray annots;
for (int i = 1; i <= reader.NumberOfPages; i++)
{
page = reader.GetPageN(i);
annots = page.GetAsArray(PdfName.ANNOTS);
for (int j = 0; j < annots.Size; j++)
{
fields.Add(annots.GetAsIndirectObject(j));
}
}
PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
stamper.Close();
reader.Close();
Upvotes: 3
Reputation: 77606
Clearly your PDF is broken. The fields are defined as widget annotations on the page level, but they aren't referenced in the /AcroForm
fields set on the document root level.
You can fix your PDF using the FixBrokenForm code sample:
PdfReader reader = new PdfReader(src);
PdfDictionary root = reader.getCatalog();
PdfDictionary form = root.getAsDict(PdfName.ACROFORM);
PdfArray fields = form.getAsArray(PdfName.FIELDS);
PdfDictionary page;
PdfArray annots;
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
page = reader.getPageN(i);
annots = page.getAsArray(PdfName.ANNOTS);
for (int j = 0; j < annots.size(); j++) {
fields.add(annots.getAsIndirectObject(j));
}
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
You should inform the creators of the tool that was used to produce the form that their PDFs aren't compliant with the PDF reference.
Upvotes: 4