Render a Record as a PDF from a Template in SuiteScript
Created: February 5, 2024
This is a sample chapter adapted from the "Rendering PDFs with SuiteScript 2.1" Cookbook, part of the SuiteScript by Example series.
SuiteScript's N/render module allows us to specify custom XML and transform it into a PDF, but it's extremely clunky to manage XML within a string. Trying to write and manage our own XML to display all the pertinent data for multiple Record types would be unwieldy.
Plus, NetSuite already has a robust PDF Template system.
How about we leverage that from our SuiteScript instead?
N/render is Server-Side Only
Before we can get to rendering shiny PDFs, there's a little setup work to do first. PDFs can only be rendered in server-side scripts, meaning we can't drop code in the browser console and expect it to work.
Instead, we'll build a Suitelet that will render our PDFs for us.
We'll start by building a custom module file. This is where we'll be adding and changing the code from the upcoming examples:
/**
* Custom module for executing N/render cookbook examples
*
* @NApiVersion 2.1
* @NModuleScope SameAccount
*
* @author Eric T Grubaugh <eric@stoic.software> (https://stoic.software/)
*/
define(['N/render'], (render) => {
const renderPdf = (response) => {
// This is where our example code will go
}
return { renderPdf }
})
- Create a folder in the File Cabinet at
/SuiteScripts/render-pdf-cookbook/
- Upload the above source code into the new folder in a file
named
render-cookbook.js
. - From now on, I will refer to this file as the "
render-cookbook
module".
Next:
/**
* Suitelet for testing PDF rendering
*
* @NApiVersion 2.1
* @NModuleScope SameAccount
* @NScriptType Suitelet
*/
define(['./render-cookbook', 'N/https'], (pdfCookbook, https) => {
/** @see https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4407987288.html */
const onRequest = (context) => {
log.audit({ title: `${context.request.method} request received` })
// Ignore POST requests
if (context.request.method !== https.Method.GET) {
return
}
pdfCookbook.renderPdf(context.response)
log.audit({ title: 'Request complete.' })
}
return { onRequest }
})
- Use the above source code to create a second file in the same folder as before.
- Use this second file
to create a new
Suitelet
named Render a PDF. - Create a Deployment
for the Suitelet; leave it in
Testing
status. - On the
Deployment, add a new
Link
in theLinks
sublist. Locate it somewhere accessible to the Role you'll be using to test the examples in this book. For me, using the Administrator Role, I choseClassic Center > Setup > Custom > Render a PDF
.
⚠️ If either of these code files is named differently or is not in the same folder, you will likely receive
MODULE_NOT_FOUND
errors when attempting to access the Suitelet.
This Suitelet is our test runner for working with files. Whenever we need to test one of our code examples, we access the link for the Suitelet in NetSuite's main navigation, and we can monitor the resulting Execution Logs on the Suitelet record.
For the remainder of the article, you should not need to make any modifications to the Suitelet or its source code.
Rendering a Transaction as a PDF
Replace the renderPdf
function in the render-cookbook
module as follows:
const renderPdf = (response) => {
const pdf = render.transaction({
entityId: 1280,
formId: 71
})
response.writeFile({ file: pdf, isInline: false })
}
This will result in something like:
when you navigate to the Suitelet you created previously.
render.transaction()
The N/render
module gives us several methods for leveraging NetSuite's
Advanced PDF/HTML Template system. Here, we demonstrate the
transaction()
method's
ability to render a Transaction record using the PDF Templates specified on the
Transaction Form.
const pdf = render.transaction({
entityId: 1280,
formId: 71
})
The entityId
is - despite the name - actually the internal ID of the
Transaction record we'd like to render. The formId
is the numeric internal ID
of the Transaction Form to start from.
In this specific example, 1280
is the internal ID of a Quote/Estimate record,
and 71
is the internal ID of the Standard Quote Transaction Form.
Importantly, formId
is not the ID of a specific PDF Template. Instead,
NetSuite inspects the Transaction Form you've selected, then uses
the Print Template
selected there.
Refresh the Suitelet's page, and you should see your transaction PDF form.
Print Modes
By default, transaction()
and its sibling methods will print the record in
either PDF or HTML format, depending on the User or the Company Preference
for PRINT USING HTML
. You can force the printing mode to one or the other by
using the printMode
option of each method and the
render.PrintMode
enumeration
Rendering other Record Types
The sibling methods for transaction()
within N/render
are:
All of these are convenience methods, abstracting the
TemplateRenderer
Object
and returning the File
instance for the PDF directly.
These methods all behave similarly, but I leave researching the specifics of each as an exercise for you.