3

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?

Im0rtality
  • 3,463
  • 3
  • 31
  • 41
Gregor Glinka
  • 71
  • 1
  • 5
  • Your code works on my sample PDF, can you provide the PDF that doesn't work? Also, can you check if the PDF form is using XFA by inspecting this property `form.Xfa.XfaPresent` – Chris Haas Apr 07 '14 at 13:26
  • With my pdf the xfapresent is false. But in another PDF where i can read the fields it is also false. How can I add the pdf? – Gregor Glinka Apr 07 '14 at 15:18
  • SO doesn't allow uploading of files, see this http://meta.stackexchange.com/q/4637 – Chris Haas Apr 07 '14 at 18:22
  • ok...here is the link: [PDF](http://www.unirent.de/down/ll_formular.pdf) . Hope you can help me to find out why the fields are not readable. If they are not readable by itext maybe you know another component. ty – Gregor Glinka Apr 08 '14 at 07:23
  • If it helps the PDF was created with wpcubed. – Gregor Glinka Apr 08 '14 at 13:38

4 Answers4

4

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.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thank you, Lowagie; after Fixing the PDF, I can read the form values. I will inform the tool developer. – Gregor Glinka Apr 14 '14 at 07:55
  • When I run this code, it says annots is null. How can i come over it? – Hieu Le Jun 04 '18 at 16:03
  • 1
    @hiule An interactive form without annots is an XFA Form. XFA stands for the XML Forms Architecture. It's totally different from the AcroForm technology that used widget annotations for the visual representation of fields. Please be aware that you won't get much feedback if you comment on a post dating from more than 4 years ago. – Bruno Lowagie Jun 04 '18 at 16:54
  • @BrunoLowagie I understand it now. It made me confuse because of "pdfStamper.AcroFields.Xfa". I thought it's a part of AcroForm. Thank you! – Hieu Le Jun 06 '18 at 03:01
3

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();
Gregor Glinka
  • 71
  • 1
  • 5
1

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.

User2012384
  • 4,769
  • 16
  • 70
  • 106
Ranch Camal
  • 501
  • 1
  • 4
  • 12
0

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();
Simon
  • 1,890
  • 19
  • 26