Working with PDF forms on Android

Jul 18, 2015   //   by Theo   //   Blog  //  No Comments

Background

Traditionally, working with PDF on Android has been hard because there is no PDF support built into the OS. To be able to work with PDF across the major Android OS versions in use, you typically have to resort to third-party commercial libraries or online services that can process PDF files remotely. Both approaches have their problems: commercial PDF libraries require thousands of dollars in yearly maintenance while online services introduce significant delays in processing, plus don’t work when Internet is not available.

Recent Developments

Recently, some new options have emerged that make working with PDF on Android much more convenient. A new project called  PDFBox-Android brings the power of the well-known Apache PDFBox open-source library to Android. You can now create, alter, merge, split and render PDF documents easily and for free. The main advantages of this solution are:

  • Open source license based on Apache 2 that allows you to use the component in commercial applications without onerous license fees
  • Pure Java library that does not require separate C/C++ libraries for different architectures
  • Large community of Java developers already using this library for the desktop. That means that there are numerous StackOverflow threads and blog posts to help you with common usage scenarios.

The Android OS has also added some PDF functionality in recent versions. In API level 19 Google introduced a new class called PdfDocument to generate PDF documents from native content, and in API level 21 Google added another class called PdfRenderer to allow rendering a PDF document. However, the usefulness of these options is limited because they are not available in older Android versions currently in use.

Filling a PDF Form

In this post we will use PDFBox-Android to fill a PDF form. We will use an AcroForms PDF with pre-defined textbox and checkbox fields. In the next part of this series, we will look at inserting a signature into the PDF.

The actual form we will use in this blog post can be found here. If you want to create your own small forms with AcroForm fields, you can use the free PDFescape online form editor. When working professionally with large forms that have a lot of fields, you should probably use Adobe Acrobat because it has automatic AcroForm field insertion can save you from the drudgery of manually defining AcroForm fields.

Adding PDFBox-Android to your Project

If you are using Gradle and Android Studio, you can simply add the jcenter repository and a reference to PDFBox-Android 1.8.9.0 (latest version as of now), as shown below:

In your project’s build.gradle:

allprojects {
    repositories {
        jcenter()
    }
}

In your app’s build.gradle:

dependencies {
 compile 'org.apache:pdfbox-android:1.8.9.0'
}

Filling the AcroForm Fields

To get started, we’ll create a skeleton function called fillPdf that opens a PDF, retrieves the AcroForm, makes changes to fields and then closes and save the changes to another PDF file.

public fillPdf(String inFileName, String outFileName)
{
    try
    {
        // Load the document
        document = PDDocument.load(inFileName);

        // Get the AcroForm
        PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
        PDAcroForm acroForm = docCatalog.getAcroForm();

        // TODO: Set fields 

        // Save document
        document.save(outFileName);

        // Close document
        document.close();
    }
    catch (IOException ioe)
    {
        ioe.printStackTrace();
    }
}

We change the fields using the setTextField and setCheckBox functions whose implementation is shown below:

public void setTextField(PDAcroForm acroForm, String textFieldName, String text)
{
    PDFieldTreeNode treeNode = acroForm.getField(textFieldName);
    if( treeNode != null )
    {
        treeNode.setValue(text);
    }
    else
    {
        Log.e(TAG, "No text field found with name:" + name);
    }
}

public void setCheckBoxField(PDAcroForm acroForm, String checkBoxFieldName, boolean isChecked)
{
    PDFieldTreeNode treeNode = acroForm.getField(checkBoxFieldName);
    if( treeNode != null && treeNode instanceof PDCheckbox)
    {
        if (isChecked)
        {
            ((PDCheckBox)treeNode).check();
        }
        else
        {
            ((PDCheckBox)treeNode).unCheck();
        }
    }
    else
    {
        Log.e(TAG, "No checkbox field found with name:" + name);
    }
}

Finally, we will need to add the calls to edit the form fields in the fillPdf function, replacing the TODO. The final code for fillPdf is shown below.

public fillPdf(String inFileName, String outFileName)
{
    try
    {
        // Load the document
        document = PDDocument.load(inFileName);

        // Get the AcroForm
        PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
        PDAcroForm acroForm = docCatalog.getAcroForm();

        // Set AcroForm fields
        setTextField(acroForm, "name", "John Doe");
        setCheckboxField(acroForm, "male", true);
        setTextField(acroForm, "address", "123 Broadway");
        setTextField(acroForm, "city", "New York");
        setTextField(acroForm, "state", "NY");
        setTextField(acroForm, "zip", "10001");

        // Save document
        document.save(outFileName);

        // Close document
        document.close();
    }
    catch (IOException ioe)
    {
        ioe.printStackTrace();
    }
}

Stay tuned for the next part

In the next part we will look at adding the signature into the PDF document. Until then, let us know of any questions in the comments section.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>