I have a pdf file which is a Formular. To fill the fields, first i tried to get the names of the fields with iText7 (C#). I can find every Field and Name, except the checkboxes. Can someone help me?
protected void ReadPDF(string dest)
{
PdfDocument doc = new (new PdfReader(SRC), new PdfWriter(dest));
var form = PdfAcroForm.GetAcroForm(doc, true);
var fields = form.GetFormFields();
foreach (KeyValuePair<string, PdfFormField> field in fields)
Console.WriteLine("{0} : {1}",field.Key, field.Value.GetValue());
doc.Close();
}
I would like to share a bit of background on what PDF specification says about different acroform fields and how to extract those fields using iText 7.
If you refer ISO specification section 12.7.4.2 Button Fields section , it says
A button field (field type Btn) represents an interactive control on the screen that the user can manipulate with the mouse. There are three types of button fields: •A pushbutton is a purely interactive control that responds immediately to user input without retaining a permanent value (see 12.7.4.2.2, “Pushbuttons”). •A check box toggles between two states, on and off (see 12.7.4.2.3, “Check Boxes”). •Radio button fields contain a set of related buttons that can each be on or off. Typically, at most one radio button in a set may be on at any given time, and selecting any one of the buttons automatically deselects all the others. (There are exceptions to this rule, as noted in "Radio Buttons.") For button fields, bits 15, 16, 17, and 26 shall indicate the intended behaviour of the button field.
If you refer Table 226 – Field flags specific to button fields, you would notice that it is possible to detect the intended behavior of button using Bit Position 15,16, 17 and 26.
iText 7 has implemented one single class for Button which is PdfButtonFormField. If we inspect the Button field, you would notice that the /FT: /Btn for all the three types i.e. Radio or Push Button Or checkbox. iText 7 has implemented PdfTextFormField to handle text field single/multiline, PdfSignatureFormField to handle signature field and PdfChoiceFormField to select one or more options from a list or combo box. Choice fields can be configured in a way that people can select only one of the options, or several options.
It is possible to detect the button type but for that you first have to fetch the acroform field. Once you have a list of acroform fields, you can loop over each field and use an instance of operator to check if the field is of type PDFButtonFormField or PDFTextFormField or PdfChoiceFormField.
Once you filter out this data then you can use methods like buttonField.isPushButton() or buttonField.isRadio() or choiceField.isCombo() or textField.isMultiline() depending upon your requirement.
I am sharing a sample code that can help you to implement this behavior.
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
// Loop over the fields and get info about them
Set<String> fields = form.getFormFields().keySet();
for (String key : fields) {
writer.print(key + ": ");
PdfName type = form.getField(key).getFormType();
//System.out.println("Name of field is : "+key + " type of field is : "+type);
if (0 == PdfName.Btn.compareTo(type)) {
PdfButtonFormField buttonField = (PdfButtonFormField)form.getFormFields().get(key);
System.out.println("Field : "+key + " type of button is : Push : "+buttonField.isPushButton() + " Radio button: "+buttonField.isRadio());
writer.println("Button");
} else if (0 == PdfName.Ch.compareTo(type)) {
PdfChoiceFormField choiceField = (PdfChoiceFormField)form.getFormFields().get(key);
System.out.println("Type of choice field : Is it Combo : "+choiceField.isCombo()+ " Is it Dropdown : "+choiceField.isMultiSelect());
writer.println("Choicebox");
} else if (0 == PdfName.Sig.compareTo(type)) {
PdfSignatureFormField signatureField = (PdfSignatureFormField)form.getFormFields().get(key);
writer.println("Signature");
} else if (0 == PdfName.Tx.compareTo(type)) {
PdfTextFormField textField = (PdfTextFormField)form.getFormFields().get(key);
System.out.println("Type of text field : Is it multi line : "+textField.isMultiline());
writer.println("Text");
}else {
writer.println("?");
System.out.println("Nothing matched...");
}
}