Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
            }
        }
like image 312
Sankar M Avatar asked Feb 20 '23 10:02

Sankar M


2 Answers

The following code may help you out, if you still need it. It only works for AcroForms

int BUTTON = 1;
int CHECK_BOX = 2;
int RADIO_BUTTON = 3;
int TEXT_FIELD = 4;
int LIST_BOX = 5;
int COMBO_BOX = 6;

PdfReader pdfReader = new PdfReader(path);
AcroFields af = pdfReader.AcroFields;

foreach (var field in af.Fields)
{
    bool isRadio = RADIO_BUTTON == af.GetFieldType(field.Key));
}

Edit:

Also, field.Key is the name of the field and field.Value is the value at it.

For checkboxes, if(field.Value == "Yes") then it is selected... if it is anything else, it is not selected.

Edit:

And I just found how tro get Radio Button options, if you are needing them.

myKey k = new myKey(field.Key, af.GetField(field.Key), af.GetFieldType(field.Key));
if (k.isRadio())
{
    try { k.options.AddRange(af.GetAppearanceStates(k.key)); }
    catch { }
}
Keys.Add(k);
like image 148
Mike Avatar answered Mar 01 '23 09:03

Mike


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();
        }
    }
}
like image 43
Chris Haas Avatar answered Mar 01 '23 10:03

Chris Haas