Read Check Box, Radio Button Name and values from PDF using iText Sharp

Sankar M picture Sankar M · May 18, 2012 · Viewed 11.3k times · Source

I have a fillable PDF contains CheckBoxes and RadioButtons and TextBox.

How do i get the CheckBox Name and its value also how do we know that it is a checkbox / Radio Button?

i'm using iTextSharp and have look at my below code

 PdfReader pdfReader = new PdfReader(FileName);
 pdfReader.SelectPages("37");
        MemoryStream oStream = new MemoryStream();
        PdfStamper stamper = new PdfStamper(pdfReader, oStream);
        AcroFields form = stamper.AcroFields;
        if (form.Fields.Count() > 0)
        {
            IDictionary<string,AcroFields.Item> oDic= form.Fields;

            foreach (string FieldName in oDic.Keys)
            {
                //FieldName - CheckBox name; i need to confirm that is a Checkbox...
            }

            foreach (AcroFields.Item oItem in oDic.Values)
            {
                // how do we get check box values
            }
        }

Answer

Chris Haas picture Chris Haas · May 18, 2012

Radio buttons, checkbox and buttons are all actually the same type of field but with different flags set. You can see the flags in the PDF Spec section 12.7.4.2.1 Table 226.

int ffRadio = 1 << 15;      //Per spec, 16th bit is radio button
int ffPushbutton = 1 << 16; //17th bit is push button

For a given Field you want to get the Widgets associated with it. Usually this is just one but can be more so you should account for this.

PdfDictionary w = f.Value.GetWidget(0);

Button fields will have their field type (/Ft) set to /Btn so check for that

if (!w.Contains(PdfName.FT) || !w.Get(PdfName.FT).Equals(PdfName.BTN)) {continue;/*Skipping non-buttons*/ }

For the current Widget get the optional field flags (/Ff) value or use zero if it doesn't exist.

int ff = (w.Contains(PdfName.FF) ? w.GetAsNumber(PdfName.FF).IntValue : 0);

Then just some simple math:

if ((ff & ffRadio) == ffRadio) {
    //Is Radio
} else if (((ff & ffRadio) != ffRadio) && ((ff & ffPushbutton) != ffPushbutton)) {
    //Is Checkbox
} else {
    //Regular button
}

Below is a full-working C# WinForm 2011 app targeting iTextSharp 5.2.0 that shows off all of the above looking at a file called Test.pdf living on your desktop. Just add some logic to the conditionals to handle each button type.

using System;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication3 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");
            PdfReader reader = new PdfReader(testFile);
            var fields = reader.AcroFields;

            int ffRadio = 1 << 15;      //Per spec, 16th bit is radio button
            int ffPushbutton = 1 << 16; //17th bit is push button
            int ff;
            //Loop through each field
            foreach (var f in fields.Fields) {
                //Get the widgets for the field (note, this could return more than 1, this should be checked)
                PdfDictionary w = f.Value.GetWidget(0);
                //See if it is a button-like object (/Ft == /Btn)
                if (!w.Contains(PdfName.FT) || !w.Get(PdfName.FT).Equals(PdfName.BTN)) { continue;/*Skipping non-buttons*/ }
                //Get the optional field flags, if they don't exist then just use zero
                ff = (w.Contains(PdfName.FF) ? w.GetAsNumber(PdfName.FF).IntValue : 0);
                if ((ff & ffRadio) == ffRadio) {
                    //Is Radio
                } else if (((ff & ffRadio) != ffRadio) && ((ff & ffPushbutton) != ffPushbutton)) {
                    //Is Checkbox
                } else {
                    //Regular button
                }
            }
            this.Close();
        }
    }
}