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?
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.
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();
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.Length; 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.