Search code examples
c#.netpdfitextitext7

Fill pdf check field with iText7


I'm trying check a checkbox on my PDF with iText7. But instead of checking only one field, it's checking all fields

What I need:

img

What I get:

img

PDF when editing:

img

I think the exported value has something to do with it. But I don't kown what to do.

img

My code:

private static void CreatePdf(string output)
{
    using var _pdfDoc = new PdfDocument(new PdfReader("CheckTest.pdf"), new PdfWriter(output));
    var form = PdfAcroForm.GetAcroForm(_pdfDoc, true);
    var check = form.GetField("Check");
    check.SetValue("01");
}

PDF: Link

Someone know how to check it properly?

Thanks!


Solution

  • First of all, the PDF essentially mis-uses PDF AcroForm check box fields as radio buttons instead of using genuine PDF AcroForm radio button fields.

    The PDF specification does not clearly specify what a PDF viewer should do in such a case (it's mis-use after all) but the developers of the PDF form generator in question probably have experimented and determined that in the most widely used PDF viewer, Adobe Acrobat Reader, this mis-use works just as they want.

    As this use is beyond specification, though, other PDF processors processing such PDFs may produce completely different results without doing anything wrong.


    That being said, there is a way to fill the form using iText and achieve results similar to those generated by Adobe Reader.

    The problem at hand is that iText by default for all form field types except actual AcroForm radio button fields generates new appearances in a way appropriate for the field type when setting the field value. In your document there are three check box field objects with the same name. Thus, they are considered a single check box with three widgets representing the same value, and so the appearances are generated as you observe.

    But you can tell iText to not generate new appearances, using another SetValue overload accepting an additional boolean value, simply replace

    check.SetValue("01");
    

    by

    check.SetValue("01", false);
    

    Now iText makes do with the existing appearances, so only the field becomes checked that has an appearance for that "01" value.

    Beware, only prevent iText from generating appearances in cases like this. In case of text fields, for example, not updating the appearances would cause the old appearances with the former field content to continue to be displayed even though the internal field value changed.