PDFlib Cookbook

cookbook

pdf_import/fill_imported_form_fields

Import all pages from a PDF document and fill form fields.

Download Java Code  Switch to PHP Code  Show Output 

/*
 * Fill form fields:
 * Import all pages from a PDF document and fill form fields.
 * Actions and JavaScript are also imported.
 * 
 * We apply the following simplified approach to filling the form fields:
 * - all fields are highlighted with a colorized border
 * - text fields are filled with their names
 * - checkboxes and radiobuttons are activated
 * - comboboxes and listboxes are populated with a few list items
 * - pushbuttons are supplied a new caption
 * - signature fields are highlighted, but could also get a new appearance
 *
 * Required software: PDFlib+PDI or PDFlib Personalization Server (PPS) 10
 * Required data: PDF input file, Noto fonts for field contents
 */
package com.pdflib.cookbook.pdflib.pdf_import;

import com.pdflib.pdflib;
import com.pdflib.PDFlibException;

public class fill_imported_form_fields {
    public static void main(String argv[]) {
        /* This is where the data files are. Adjust as necessary. */
        String searchpath = "../input";

        /* By default annotations are also imported. In some cases this
         * requires the Noto fonts for creating annotation appearance streams.
         * We therefore set the searchpath to also point to the font directory.
         */
        String fontpath = "../resource/font";
        String outfile = "fill_imported_form_fields.pdf";
        String title = "Fill imported form fields ";

        pdflib p = null;
        String pdffile = "form_fields_pdfua1_input.pdf";
        int indoc, pageno, endpage, page;
        int exitcode = 0;

        try {
            p = new pdflib();
            int font;

            p.set_option("searchpath={" + searchpath + "}");

            p.set_option("searchpath={" + fontpath + "}");

            /* This means we must check return values of load_font() etc. */
            p.set_option("errorpolicy=return");

            if (p.begin_document(outfile, "") == -1)
                throw new Exception("Error: " + p.get_apiname() + ": "
                        + p.get_errmsg());

            p.set_info("Creator", "PDFlib Cookbook");
            p.set_info("Title", title);
            
            font = p.load_font("NotoSerif-Regular", "", "");
            if (font == -1)
                throw new Exception("Error: " + p.get_apiname() + ": "
                        + p.get_errmsg());
            
            /* Open the input PDF */
            indoc = p.open_pdi_document(pdffile, "usejavascript");
            if (indoc == -1)
                throw new Exception("Error: " + p.get_apiname() + ": "
                        + p.get_errmsg());

            endpage = (int) p.pcos_get_number(indoc, "length:pages");

            /* Loop over all pages of the input document */
            for (pageno = 1; pageno <= endpage; pageno++) {
                int fieldcount;

                page = p.open_pdi_page(indoc, pageno, "");

                if (page == -1)
                {
                    System.err.println("Error: " + p.get_errmsg());
                    continue;
                }
                /* Dummy page size; will be adjusted by p.fit_pdi_page() */
                p.begin_page_ext(100, 100, "");

                /* Place the imported page on the output page and
                * adjust the page size. If the page contains form fields
                * these are also imported.
                */
                p.fit_pdi_page(page, 0, 0, "adjustpage usefields=all useactions");

                /* Enumerate imported form fields */
                fieldcount = (int) p.pcos_get_number(indoc, "length:pages[" + (pageno-1) +"]/fields");

                if (fieldcount == 0)
                    System.err.println("no form fields found on page " + pageno + "\n");
                else
                	System.err.println("processing page " + pageno + "\n");

                for (int f = 0; f < fieldcount; f++) {
                    String fieldname;
                    String fieldtype;
                    String optlist;

                    fieldname = p.pcos_get_string(indoc, "pages[" + (pageno-1) + "]/fields["+ f + "]/fullname");
                    fieldtype = p.pcos_get_string(indoc, "pages[" + (pageno-1) + "]/fields[" + f +"]/type");

                    /* Process field depending on its type */
                    switch (fieldtype) {
                    case "textfield":
                        System.err.println("filling " + fieldtype +" "+ f + ": '" + fieldname + "'\n");

                        // Fill the field with its own name
                        optlist = "currentvalue={" + fieldname + "} font=" + font + " bordercolor=pink";
                        p.create_field(0, 0, 0, 0, fieldname, "", optlist);
                        break;
                    
                    case "radiobutton":                      
                        // Highlight the field
                        optlist = "bordercolor=pink";

                        if (fieldname.length() > 2 && fieldname.substring(fieldname.length()-2).equals("#0"))
                        {
                            System.err.println("Activating " + fieldtype +" "+ f + ": '" + fieldname + "'\n");

	                        // Activate the first button in the group
                        	optlist += " currentvalue=On";
                        }
                        else
                        {
                            System.err.println("Highlighting " + fieldtype +" "+ f + ": '" + fieldname + "'\n");
                        }
                        p.create_field(0, 0, 0, 0, fieldname, "", optlist);
                        break;
                        
                    case "checkbox":
                        System.err.println("activating " + fieldtype +" "+ f + ": '" + fieldname + "'\n");
       
                        // Activate all boxes
                        optlist = "currentvalue=On bordercolor=pink";
                        p.create_field(0, 0, 0, 0, fieldname, "", optlist);
                        break;
                        
                    case "combobox":
                        System.err.println("highlighting and populating " + fieldtype +" field "+ f + ": '" + fieldname + "'\n");
                            
                        // Highlight the field
                        optlist = "itemtextlist={item1 item2 item3} currentvalue=item1 bordercolor=pink font=" + font;
                        p.create_field(0, 0, 0, 0, fieldname, "", optlist);
                        break;

                    case "listbox":
                        System.err.println("highlighting and populating " + fieldtype +" field "+ f + ": '" + fieldname + "'\n");
                        
                        // Highlight the field
                        optlist = "itemtextlist={item1 item2 item3} currentvalue={1} bordercolor=pink font=" + font;
                        p.create_field(0, 0, 0, 0, fieldname, "", optlist);
                    	break;
                    	
                    case "pushbutton":
                        System.err.println("adding caption for " + fieldtype +" field "+ f + ": '" + fieldname + "'\n");
                        
                        // Add caption (descriptive text) and highlight field border
                        optlist = "caption={push me} bordercolor=pink font=" + font;
                        p.create_field(0, 0, 0, 0, fieldname, "", optlist);
                    	break;
                    	
                    case "signature":
                        /*
                         * Invisible signature fields are ignored upon import.
                         * In this case we risk an error message from PDF_create_field()
                         * since the selected field isn't available for filling.
                         * Therefore we must detect and skip empty signature fields here.
                         */
                        double llx = p.pcos_get_number(indoc, "pages[" + (pageno-1) + "]/fields[" + f +"]/Rect[0]");
                        double lly = p.pcos_get_number(indoc, "pages[" + (pageno-1) + "]/fields[" + f +"]/Rect[1]");
                        double urx = p.pcos_get_number(indoc, "pages[" + (pageno-1) + "]/fields[" + f +"]/Rect[2]");
                        double ury = p.pcos_get_number(indoc, "pages[" + (pageno-1) + "]/fields[" + f +"]/Rect[3]");
                        
                        if (llx == urx || lly == ury)
                        {
                        	System.err.println("ignoring empty signature field " + f + ": '" + fieldname + "'\n");
                        }
                        else
                        {
	                        // Highlight field border
	                    	// Use "fieldcontents" to change the appearance
	                        System.err.println("highlighting " + fieldtype +" field "+ f + ": '" + fieldname + "'\n");
	                        optlist = "bordercolor=pink";
	                        p.create_field(0, 0, 0, 0, fieldname, "", optlist);
                        }
                    	break;
                    	
                    // The remaining pCOS types don't designate usable fields; nothing to do
                    case "container":		// node in the form tree which is not a form itself
                    case "radiogroup":		// parent of a group of radio buttons
                    default:
                        System.err.println("skipping " + fieldtype +" "+ f + ": '" + fieldname + "'\n");
                        break;
                    }
                }
                p.close_pdi_page(page);
                p.end_page_ext("");

            }

            p.end_document("");
        }
        catch (PDFlibException e) {
            System.err.println("PDFlib exception occurred:");
            System.err.println("[" + e.get_errnum() + "] " + e.get_apiname()
                + ": " + e.get_errmsg());
            exitcode = 1;
        }
        catch (Exception e) {
            System.err.println(e);
            exitcode = 1;
        }
        finally {
            if (p != null) {
                p.delete();
            }
            System.exit(exitcode);
        }
    }
}