
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 02-18-2021 02:03 AM
ServiceNow recently released a new plugin for the platform (Paris onwards) to enable better support for custom PDF generation using script. Unfortunately the only documentation on this new feature set you will find is in KB0866613, which does not go very far in explaining how to use the API. I'm sure ServiceNow will eventually document this, or even build some full featured platform functionality around it, but for now I hope this article will get you started.
The new API appears to be based on iText7, which is a major improvement over the old GeneralPDF that was based on iText5. The newer version of iText is much better at handling HTML conversion, and once you start to explore the feature set, there is quite a lot you can do with just plain HTML and CSS.
API Overview
At the time of writing this article, there are two known methods available on the API.
convertToPDFWithHeaderFooter
Parameter | Type | Description |
html | String | The HTML content to convert to a PDF |
targetTable | String | The table name to attach the generated PDF to |
targetSysId | String | sys_id of the record to attach the generated PDF to |
filename | String | The file to to save the generated PDF as |
pageProperties | Object | Javascript object with properties used during PDF generation |
fontSysId | String | sys_id of a font family record on the 'sys_pdf_generation_font_family' table |
pageProperties
property | Type | Description |
HeaderImageAttachmentId | String | sys_id of an attachment record |
HeaderImageAlignment | String | One of: 'LEFT', 'CENTER', 'RIGHT' |
PageSize | String | One of: 'LEGAL', 'LETTER', 'A4' |
GeneratePageNumber | String | One of: 'true', 'false' |
TopOrBottomMargin | String | Number as a string e.g. '72' |
LeftOrRightMargin | String | Number as a string e.g. '36' |
Example
var pageProperties = {
HeaderImageAttachmentId: 'attachment_sys_id',
HeaderImageAlignment: 'LEFT',
PageSize: 'A4',
GeneratePageNumber: 'true',
TopOrBottomMargin: '72',
LeftOrRightMargin: '36'
};
var html = '<h1>Hello World</h1>';
new sn_pdfgeneratorutils.PDFGenerationAPI().convertToPDFWithHeaderFooter(html, 'incident', 'incident_sys_id', 'My First PDF', pageProperties, 'font_family_sys_id');
convertToPDF
Parameter | Type | Description |
html | String | The HTML content to convert to a PDF |
targetTable | String | The table name to attach the generated PDF to |
targetSysId | String | sys_id of the record to attach the generated PDF to |
filename | String | The file to to save the generated PDF as |
fontSysId | String | sys_id of a font family record on the 'sys_pdf_generation_font_family' table |
Example
var html = '<h1>Hello World</h1>';
new sn_pdfgeneratorutils.PDFGenerationAPI().convertToPDF(html, 'incident', 'incident_sys_id', 'My First PDF', 'font_family_sys_id');
On the face of it, it would appear as though the convertToPDFWithHeaderFooter is the more flexible of the two methods, however as you'll see below, we can actually control the entire document ourselves with HTML and CSS and just use the convertToPDF method.
CSS 3 Paged Media
The CSS 3 specification sets out functionality for paged media, for example printing. When it comes to PDF we can use the paged media rules to define how the document should be generated using the ServiceNow PDFGenerationAPI / iText7.
@page rule
The @page rule allows us to specify details about the pages we will be generating, including the margins, size, orientation, page numbering rules etc.
Example
<style>
@page {
size: A4 landscape;
margin-left: 1cm;
margin-top: 3cm;
margin-right: 1cm;
margin-bottom: 3cm;
@bottom-right {
font-family: sans-serif;
font-weight: bold;
font-size: 1em;
content: counter(page);
}
}
</style>
<h1>
Hello World!
</h1>
Resulting PDF
Headers and Footers
The creation of headers and footers is equally as easy. This uses a feature called 'Running elements'. At first they may not make much sense in how you define them, but see the below for an example.
<style>
@page {
size: A4 landscape;
margin-left: 1cm;
margin-top: 3cm;
margin-right: 1cm;
margin-bottom: 3cm;
@top-center {
font-family: sans-serif;
font-weight: bold;
font-size: 1em;
content: element(runningPageHeader);
}
}
#pageHeader {
position: running(runningPageHeader)
}
</style>
<div id="pageHeader">
My Header!
</div>
<h1>
Hello World!
</h1>
Resulting PDF
How this works
The div element with the id 'pageHeader' would normally be rendered in the position its included in the code on the page, however the style block of the code contains a CSS rule for the element #pageHeader, specifying position: running(runningPageHeader). This removes the element from the rendered page and adds it into a css variable, in our case the variable is called 'runningPageHeader'. Once the content is in the variable, we can use that same variable name to include it as content in the @top-center rule using content: element(runningPageHeader).
This can be a difficult concept to get your head around at first, and it can get more complicated when you want to include a page number in your custom HTML header content too. For example:
<style>
@page {
size: A4 landscape;
margin-left: 1cm;
margin-top: 3cm;
margin-right: 1cm;
margin-bottom: 3cm;
@top-center {
font-family: sans-serif;
font-weight: bold;
font-size: 1em;
content: element(runningPageHeader);
}
}
#pageHeader {
position: running(runningPageHeader)
}
#currentPageNumber:before {
content: counter(page)
}
</style>
<div id="pageHeader">
My Header! <span id="currentPageNumber"/>
</div>
<h1>
Hello World!
</h1>
Resulting PDF
Images
Images are also possible with relative ease. You can use the usual img elements in your html, and even use absolute URLs to image content, be aware though that if the image is hosted on your ServiceNow instance, you need to make sure the image is publicly accessible. Attachments against records won't work unfortunately as the PDF generation API is not authenticated to your instance.
Example
<style>
@page {
size: A4 landscape;
margin-left: 1cm;
margin-top: 3cm;
margin-right: 1cm;
margin-bottom: 3cm;
@top-center {
font-family: sans-serif;
font-weight: bold;
font-size: 1em;
content: element(runningPageHeader);
}
}
#pageHeader {
position: running(runningPageHeader)
}
#currentPageNumber:before {
content: counter(page)
}
</style>
<div id="pageHeader">
My Header! <span id="currentPageNumber"/>
</div>
<h1>
Hello World!
</h1>
<img src="URL_TO_IMAGE" width="100px"/>
Resulting PDF
Fonts
It is possible to add and use custom fonts into the PDFs that you generate. I've only tried this with TTF (TrueType) fonts, though it may work with other formats too. It's possible to add more than one font to a PDF, see the following example.
- Create a new Font Family [sys_pdf_generation_font_family] record
- fill in the name field with whatever you like, it doesn't make any difference to the process.
- Save the record
- Attach your font files to the record.
When using the API, the last parameter of both methods is the font family sys_id, you can only supply one sys_id to the method, which is why you add multiple fonts to the same Font Family record.
To use the font in your document, you simply specify the font-family CSS attribute in your CSS
Example
<style>
@page {
size: A4 landscape;
margin-left: 1cm;
margin-top: 3cm;
margin-right: 1cm;
margin-bottom: 3cm;
@top-center {
font-family: sans-serif;
font-weight: bold;
font-size: 1em;
content: element(runningPageHeader);
}
}
#pageHeader {
position: running(runningPageHeader)
}
#currentPageNumber:before {
content: counter(page)
}
.angry-birds-font {
font-family: AngryBirds;
}
.flow-font {
font-family: Flow;
}
</style>
<div id="pageHeader">
My Header! <span id="currentPageNumber"/>
</div>
<h1 class="flow-font">
Hello World!
</h1>
<h1 class="angry-birds-font">
Angry Birds
</h1>
Resulting PDF
Summary
Hopefully this article has helped you get to grips with the new PDFGenerationAPI. I have only scratched the surface of the CSS paged media rules, but a little Googling around should get you loads of information on how to use it.
Why not have a play with this on your developer instance and post some screenshots here to show everyone else what you've been able to achieve, I'd love to see some of what you've managed to create.
As always, if this content has helped you, please remember to mark it as helpful so that it can reach as many people as possible.
Callum
- 81,457 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Where i "put" the "CSS 3 Paged Media" ? In the template or in the business rule?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hey, would it be possible to save the pdf in the sys_attachment table so i could use the url as a download link?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello,
I used this API to export the knowledge article that attaches the file to sys_attachment table from where it can be downloaded via a button in portal. I noticed that pdf does not contain images for those articles with 'Display attachments' option set to true whereas the images are included if the option is not enabled. Has anyone faced a similar scenario and found a solution?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
page numbering can be added by using CSS on your page:
@page { @bottom-left { content: counter(page) ' of ' counter(pages); } }
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @Callum Ridley1 ,
Thank you for the article.
Can you please have a look at my requirement.
Requirement : Once a request is submitted through the portal, the form-level variables must be automatically populated in to a customized template and attach to the submitted request.
Suppose the form has three variables - Requested for, Company and Date. Once, these fields are filled and form is submitted, these variables should be populated in a custom pdf like below.
Dear (Requested for),
I'm working for (Company) till (Date)
It should automatically fill these details based on the request and get attached to post submission.
Is this feasible in Servicenow.
Please guide me on this.
Thank you in Advance.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@Callum Ridley1 I wanted to create "Table of Contents" dynamically. And I found "documentConfiguration" which can be used as per the below syntax.
convertToPDFWithHeaderFooter(String html, String targetTable, String targetTableSysId, String pdfName, Object headerFooterInfo, String fontFamilySysId, Object documentConfiguration).
But not sure how to use it? Can you explain a bit about it how we can utilize this functionality?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Have you run into issues where converting the HTML results in misalignment? We're dealing with that at the moment and I've not yet found a solution.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
How to show this in a UI page or in widget in full screen any idea?

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
This article really saved me! Beautifully done sir! 😁
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi,
Thanks for this great article. I have a problem with this method as it won't allow me to set the font. If one of the word uses macron, it changes the default font to Times New Roman. This is the method I'm having problem with:
fillFieldsAndMergeSignature
Thanks!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @Callum Ridley1 I have created a UI action for this such that whenever I click on that generate PDF button it will generate the pdf of my form . But in my form I have few HTML type fields in which user can add a image , in my pdf I am only getting the text for those fields , I want the images and the attachments that are associated with the page in this Discussion with Complainant, Discussion with Witnesss are the html fields . Is there any way to show the images present in that field in the pdf ?
<p> </p>
<p style="text-align: center;"><span style="text-decoration: underline;"><span style="font-size: 14pt;">SafeSpace Complaint Form</span></span></p>
<table style="border-collapse: collapse; width: 100.849%; height: 197.2px;" border="1">
<tbody>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Case Number</td>
<td style="width: 49.9905%; height: 19.9px;">case_number</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Requested For</td>
<td style="width: 49.9905%; height: 19.9px;">requested_for</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Meeting ID</td>
<td style="width: 49.9905%; height: 19.9px;">meeting_id</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Category</td>
<td style="width: 49.9905%; height: 19.9px;">category</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Subcategory</td>
<td style="width: 49.9905%; height: 19.9px;">subcategory</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Business</td>
<td style="width: 49.9905%; height: 19.9px;">businessunit</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Geo</td>
<td style="width: 49.9905%; height: 19.9px;">geo</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Location</td>
<td style="width: 49.9905%; height: 19.9px;">location</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">Assignment group</td>
<td style="width: 49.9905%; height: 19.9px;">assignment_group</td>
</tr>
<tr style="height: 18.1px;">
<td style="width: 49.9905%; height: 18.1px;">Assigned to</td>
<td style="width: 49.9905%; height: 18.1px;">assigned_to</td>
</tr>
</tbody>
</table>
<table style="border-collapse: collapse; width: 100.7%;" border="1">
<tbody>
<tr>
<td style="width: 49.9905%; height: 19.9px;">Additional assignee</td>
<td style="width: 49.96%;">additional_assignee_list</td>
</tr>
<tr>
<td style="width: 50.0267%;">Short Description</td>
<td style="width: 49.96%;">short_description</td>
</tr>
<tr>
<td style="width: 50.0267%;">Description</td>
<td style="width: 49.96%;">description</td>
</tr>
<tr>
<td style="width: 50.0267%;">Discussion with Complainant</td>
<td style="width: 49.96%;">dwc</td>
</tr>
<tr>
<td style="width: 50.0267%;">Discussion with Respondent</td>
<td style="width: 49.96%;">dwr</td>
</tr>
<tr>
<td style="width: 50.0267%;">Discussion with Witnesses</td>
<td style="width: 49.96%;">dww</td>
</tr>
<tr>
<td style="width: 50.0267%;">Guilty of Charges</td>
<td style="width: 49.96%;">goc</td>
</tr>
<tr style="height: 19.9px;">
<td style="width: 50.0267%;">Recommendation</td>
<td style="width: 49.96%;">recommendation</td>
</tr>
<tr>
<td style="width: 50.0267%;">Close code</td>
<td style="width: 49.96%;">close_code</td>
</tr>
<tr>
<td style="width: 50.0267%;">Close notes</td>
<td style="width: 49.96%;">close_notes</td>
</tr>
</tbody>
</table>
<table style="border-collapse: collapse; width: 100.647%; height: 25.4px;" border="1">
<tbody>
<tr style="height: 19.9px;">
<td style="width: 49.9905%; height: 19.9px;">State</td>
<td style="width: 50.0411%; height: 15.4px;">state</td>
</tr>
<tr>
<td style="width: 50.0411%;">Opened</td>
<td style="width: 50.0411%;">opened_at</td>
</tr>
<tr>
<td style="width: 50.0411%;">Opened by</td>
<td style="width: 50.0411%;">opened_by</td>
</tr>
</tbody>
</table>
<p style="text-align: left;"><span style="font-size: 8pt;">Generated on: generated_date_time</span></p>
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Do you have any information on how to add in data from a multirow variable set?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello everyone! I've attached different fonts, but only Flow and AngryBirds work as the author showed. I've tested other TTF (TrueType) fonts, but they don't work. Does ServiceNow have specific requirements for fonts?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @Callum Ridley1 ,
Is there any way to generate a pdf with mixed page orientation (e-g, page 11 to be landscape and the rest portrait)? Tried playing around with the page property but no luck. Named pages doesn't work either.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi, After a few months without any issues, I've just encountered an issue on a production system that bulk converts dynamically generated HTML to PDF. An exception was raised on some of the calls intermittently:
"com.snc.services.client.exception.ServerUnavailableException"
With error text "All clients inactive, refresh configuration to reset"
So it might be prudent to adjust any automated scripts to allow for this and backoff-retry or similar .
- « Previous
-
- 1
- 2
- Next »