Filling PDF forms in ServiceNow

Complex web applications often require the ability to generate documents, and PDF is the obvious format for doing so as it’s the de-facto standard for digital documents.

PDF generation in ServiceNow can be done in various ways, however today I’m going to cover what I feel is a very simple yet powerful method: leveraging the PDF form handling capabilities of the PDF Generator plugin.

The power of this method comes from the fact that any PDF form can be directly consumed, and no time needs to be spent rebuilding an existing PDF form in a format like HTML (which needs to be done when using most other methods).

I created a simple PDF form to use in my examples below, which I’ve made available for downloading from this site so that you can work along with me.

GeneralPdfUtils

The PDF Generator plugin comes with a script include called GeneralPdfUtils, which contains the majority of the functions which we can use to interact with PDF forms.

Note: usage of the PDF Generator plugin may have licensing implications.

Detecting fillable fields

Every PDF form is unique, and has different fields which can be completed. We thus need a way to get a list of all the fields that exist on the form so that we know what we can plug into it. To do this we can use the getPDFFields() function:

var pdf = new global.GeneralPdfUtils();

// Sys ID of a PDF form attached to any record
var attachmentSysId = '0fd6278d4f25c70022f40ccf0310c7c8';

var fieldsString = pdf.getPDFFields(attachmentSysId);

var fields = JSON.parse(fieldsString);

When running the above code on my example PDF, the fields variable contains the JavaScript object shown below:

{
   "Read Terms and Conditions": "",
   "First name": "",
   "Gender": "",
   "Last name": ""
}

When we fill the form later on, you will see that the function to do this ingests it’s data in this exact format. This means that now that the fields variable contains this structure, we can directly manipulate it and feed it back into the form. We could also loop over it and check if a field of that name exists on a certain table in ServiceNow. If it does, we can set that PDF form field to the value of the field in that table. This is very powerful stuff!

Detecting the types of fields

There are multiple types of fields which can exist on a PDF form. We can use the getFieldType() function to do this.

var pdf = new global.GeneralPdfUtils();

// Sys ID of a PDF form attached to any record
var attachmentSysId = '0fd6278d4f25c70022f40ccf0310c7c8';

var fieldTypesString = pdf.getFieldType(attachmentSysId);

var fieldTypes = JSON.parse(fieldTypesString);

When running the above code on my example PDF, the fieldTypes variable contains the JavaScript object shown below:

{
    "Read Terms and Conditions":
    {
        "true_value": "[Off, Yes]",
        "field_type": "2"
    },
    "First name":
    {
        "true_value": "",
        "field_type": "4"
    },
    "Gender":
    {
        "true_value": "",
        "field_type": "3"
    },
    "Last name":
    {
        "true_value": "",
        "field_type": "4"
    }
}

You can see that the Read Terms and Conditions field is a checkbox (field_type = 2) with a Yes (checked) and Off (unchecked) state. First name and Last name are both text fields (field_type = 4), and Gender is a radio field (field_type = 3).

Fill the form

We can now use the knowledge we’ve gained about the PDF form to fill in the form using the prefillPDF() function.

var pdf = new global.GeneralPdfUtils();
 
// Sys ID of an attachment
var attachmentSysId = '0fd6278d4f25c70022f40ccf0310c7c8';

var jsonObject = {
    "Read Terms and Conditions": "Yes",
    "First name": "Dylan",
    "Gender": "Male",
    "Last name": "Lindgren"
};

var jsonString = JSON.stringify(jsonObject);
 
var destinationTableName = 'incident';
var destinationTableSysId = '9de878bf4f34c300ab4450af0310c722';
 
var pdfName = 'my-completed-form.pdf';

pdf.prefillPdf(jsonString, destinationTableSysId, attachmentSysId, destinationTableName, pdfName);

If we go into the record we’ve targeted in the destinationTableSysId variable, we will see that we have a new attachment called my-completed-form.pdf which is a completed PDF form with the values we supplied!

Other functions

There’s a number of other functions in the GeneralPdfUtils script include, some of which I feel will be worth investigating:

  • isFillable()
  • mergeImageToPdf()
  • isValidPdfTemplateForPreFill()

Depending on their usefulness, I may write a follow up blog post covering under what situations one would use these, along with examples.

Conclusion

Hopefully this post has revealed a new, simple, but powerful way you can work with PDF files in ServiceNow.

Feel free to reach out to me on Twitter with any questions, or leave a comment below.

  • Abigail Diaz

    Nice post Dylan! I’m actually working with PDFs in Jakarta for an HR implementation. Have you ever had an issue with old draft PDFs getting attached to a case or incident? The draft PDF has been deleted from the Managed Documents, the HR Document templates, and even the task templates that initially referenced it. But still, the old PDF attaches, like a phantom PDF.

    • Thanks Abigail!

      No, I haven’t seen that issue before. Very strange! It sounds like something specific to your instance so I would suggest getting in contact with ServiceNow Customer Support as they will be able to help you get to the root of the issue.