DS Server

PDF Form Fields

Topic

When users return a filled-in PDF form, such as an application or an order form, your application needs the values they entered. The DocumentProcessing Web API reads the AcroForm fields of a PDF document, the interactive form fields of the PDF format, and returns each field with its name, its type, its value and its position on the page. For the opposite direction, a form that must no longer be edited, the convert endpoint replaces form fields with their current values.

How Reading Form Fields Works

The endpoint is POST /documentprocessing/pdf/acroforms/fields:

Part of the requestContent
BodyThe PDF document as a Base64 string in a JSON string, with the content type application/json
ResponseA JSON array with one object per form field

Every field has these properties:

PropertyContent
fieldNameThe name of the field
alternateFieldNameThe alternate name of the field
fieldTypeThe type of the field, such as FormTextField or FormCheckBox
boundsThe position and size of the field, an object with x, y, width and height

Depending on fieldType, a field has more properties:

Field typeProperties
FormTextFieldvalue, the text of the field
FormCheckBox, FormRadioButtonisChecked, whether the box or button is selected
FormComboBox, FormListBox, FormChoiceFieldvalue, the selected value, and options, the entries of the list, besides canEdit, sort, multiSelect, doNotSpellCheck and commitOnSelChange
FormButtonNo properties of its own

A PDF without form fields is answered with 400 Bad Request, not with an empty array. Every request needs an access token, as Authentication describes.

Read the Form Fields With curl

The following commands read the fields of invoice.pdf and print the name, the type and the value of each:

DS=http://localhost:5000
TOKEN="<access_token>"

# Wrap the Base64 string of the PDF in a JSON string
base64 -w 0 invoice.pdf | jq -Rs . > invoice.json

curl --request POST "$DS/documentprocessing/pdf/acroforms/fields" \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data-binary @invoice.json \
  --output fields.json

jq '.[] | {fieldName, fieldType, value, isChecked}' fields.json

The commands work as follows:

  • The body is the PDF as a Base64 string in a JSON string, which base64 -w 0 and jq -Rs . create.
  • The response is JSON, not Base64, so fields.json can be read as it is.
  • The last jq command prints four properties of each field. value is null for a check box, and isChecked is null for a text field.

Read the Form Fields With .NET

The package TXTextControl.DocumentServices.DocumentProcessing returns each field as an object of a class derived from FormField, in the namespace TXTextControl.DocumentServices.DocumentProcessing.PDF.AcroForms:

using TXTextControl.DocumentServices.DocumentProcessing;
using TXTextControl.DocumentServices.DocumentProcessing.OAuth;
using TXTextControl.DocumentServices.DocumentProcessing.PDF.AcroForms;

var oauthSettings = new OAuthSettings("<client ID>", "<client secret>");
var documentProcessing = new DocumentProcessing("http://localhost:5000", oauthSettings);

byte[] pdf = File.ReadAllBytes("invoice.pdf");
FormField[] fields = await documentProcessing.PDF.AcroForms.GetFields(pdf);

foreach (FormField field in fields)
{
    // Read the value from the class of the field type
    string value = field switch
    {
        FormTextField textField => textField.Value,
        FormCheckBox checkBox => checkBox.IsChecked ? "checked" : "not checked",
        FormComboBox comboBox => comboBox.Value,
        _ => ""
    };

    Console.WriteLine($"{field.FieldName} ({field.FieldType}): {value}");
}

The code works as follows:

  • The DocumentProcessing constructor takes the service URL and the credentials of a security profile, and requests an access token.
  • PDF.AcroForms.GetFields takes the PDF as a byte array and returns a FormField array.
  • FormField has the common properties FieldName, AlternateFieldName, FieldType and Bounds. The switch expression reads the value from the derived classes: FormTextField.Value, FormCheckBox.IsChecked and FormComboBox.Value, which also has Options. FormListBox derives from FormComboBox and FormRadioButton from FormCheckBox, so the switch reads list boxes and radio buttons as well.

The reference of the package names the element type of the result AcroFormField; in version 5.0.0 of the package, the class is FormField. The classes are listed in the DocumentProcessing namespace of the .NET API.

Flatten Form Fields

Flattening replaces every form field of a document with its current content, so the values become ordinary text of the document instead of fields. The convert endpoint does this when you add flattenFormFields=true, as Converting Documents shows:

base64 -w 0 document.docx | jq -Rs . > document.json

curl --request POST "$DS/documentprocessing/document/convert?returnFormat=PDF&flattenFormFields=true" \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data-binary @document.json \
  --output converted.json

jq -r . converted.json | base64 -d > flattened.pdf

In C#, the third argument of Convert flattens the form fields:

byte[] document = File.ReadAllBytes("document.docx");
byte[] flattened = await documentProcessing.Convert(document, ReturnFormat.PDF, true);

The parameter was added in version 3.4.0. Its default is false, and a value that isn't a Boolean, such as maybe, is refused with 400 and a validation error.

Fill Form Fields With Data

Form fields in a template can also receive values from JSON data when the template is merged. The merge setting formFieldMergeType decides whether form fields are left alone, preselected with the data or replaced by it, as Set Merge Options describes.

Next Steps