Example of Using Custom Data Sources for Advanced Printing

When setting up an advanced template, you can use multiple data sources. This example shows how to use a JSON object and an XML file together with NetSuite data from a saved search to create a packing slip for a customer.

The JSON object provides customer names and language preferences.

          {"customers":[ {"firstName":"John", "lastName":"Doe", "language":"English"}, {"firstName":"Anna", "lastName":"Smith", "language":"Spanish"}, {"firstName":"Peter", "lastName":"Jones", "language": "English"}
]} 

        

The XML file provides a holiday greeting in the customer’s preferred language.

          <?xml version="1.0" encoding="UTF-8"?>
<message> <engbody>Happy holidays! We are closed from Dec 22 - Jan 3. Take advantage of our great prices before Christmas!</engbody> <spbody>¡Feliz Navidad! Estamos cerrados del 22 de diciembre al 3 de enero. Aproveche nuestros excelentes precios antes de Navidad!</spbody>
</message> 

        

The advanced PDF/HTML template is edited in markup source view to incorporate the XML file and JSON object.

          <?xml version="1.0"?>
<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdf>
<head>
<macrolist> <macro id="nlheader"> <!-- XML Part --> <#if XML?has_content> <p style="color: blue"> <#if .locale?starts_with("es_")> ${XML.message.spbody} <#else> ${XML.message.engbody} </#if> </p> </#if> <!-- End XML Part --> <table class="header"> <tr> <td rowspan="3"> <span class="addressheader">${‌companyInformation.companyName}</span><br /> <span class="addressheader">${‌companyInformation.addressText}</span></td> <td align="right"><span class="title">${record@title}</span></td> </tr> <tr> <td align="right"><span class="number">#${‌record.tranid}</span></td> </tr> <tr> <td align="right">${‌record.trandate}</td> </tr> </table> </macro>
</macrolist> <style type="text/css"> table { font-family: sans-serif; font-size: 9pt; table-layout: fixed; } th { font-weight: bold; font-size: 8pt; vertical-align: middle; padding: 5px 6px 3px; background-color: #e3e3e3; } td { padding: 4px 6px; } td.addressheader { font-size: 8pt; padding-top: 6px; padding-bottom: 2px; } span.number { font-size: 16pt; }</style>
</head> <body header="nlheader" header-height="20%" padding="0.5in 0.5in 0.5in 0.5in" size="Letter"> <table style="width: 100%; margin-top: 10px;"> <tr> <td colspan="3" style="font-size: 8pt; font-weight: bold;">${record.billaddress@label}</td> <td colspan="3" style="font-size: 8pt; font-weight: bold;">${record.shipaddress@label}</td> <td colspan="5" style="font-size: 12pt; background-color: #e3e3e3; font-weight: bold;">${record.total@label?upper_case}</td> </tr> <tr> <td colspan="3" style="padding: 0;">${‌record.billaddress}</td> <td colspan="3" style="padding: 0;">${‌record.shipaddress}</td> <td align="right" colspan="5">${‌record.total}</td> </tr> </table> <table style="width: 100%; margin-top: 10px;"> <tr> <th>${record.paymentmethod@label}</th> <th>${record.otherrefnum@label}</th> <th>${record.shipmethod@label}</th> <th>${record.shipdate@label}</th> </tr> <tr> <td style="padding-top: 2px;">${‌record.paymentmethod}</td> <td style="padding-top: 2px;">${‌record.otherrefnum}</td> <td style="padding-top: 2px;">${‌record.shipmethod}</td> <td style="padding-top: 2px;">${‌record.shipdate}</td> </tr> </table> <#if record.item?has_content> <table style="width: 100%; margin-top: 10px;"> <!-- Start Items --> <#list record.item as item> <#if item_index==0> <thead> <tr> <th align="center" colspan="3">${item.quantity@label}</th> <th colspan="12">${item.item@label}</th> <th align="right" colspan="4">${item.rate@label}</th> <th align="right" colspan="4">${item.amount@label}</th> </tr> </thead> </#if> <tr> <td align="center" colspan="3" line-height="150%">${‌item.quantity}</td> <td colspan="12"> <span style="font-weight: bold; line-height: 150%;">${‌item.item}</span> <br /> ${‌item.description} </td> <td align="right" colspan="4">${‌item.rate}</td> <td align="right" colspan="4">${‌item.amount}</td> </tr> </#list> <!-- End Items --> </table> <hr style="width: 100%; color: #d3d3d3; background-color: #d3d3d3; height: 1px;" /> </#if> <table style="page-break-inside: avoid; width: 100%; margin-top: 10px;"> <tr> <td colspan="4">&nbsp;</td> <td align="right" style="font-weight: bold;">${record.subtotal@label}</td> <td align="right">${‌record.subtotal}</td> </tr> <tr> <td colspan="4">&nbsp;</td> <td align="right" style="font-weight: bold;"> ${record.taxtotal@label} ${‌record.taxrate}%) </td> <td align="right">${‌record.taxtotal}</td> </tr> <tr style="background-color: #e3e3e3; line-height: 200%;"> <td background-color="#ffffff" colspan="4">&nbsp;</td> <td align="right" style="font-weight: bold;">${record.total@label}</td> <td align="right">${‌record.total}</td> </tr> </table> <!-- JSON Part --> <#if JSON?has_content> <p style="color: red"> JSON data: </p> <table style="width: 100%; margin-top: 10px;"> <thead> <tr> <th>First Name</th> <th>Last Name</th> <th>Language</th> </tr> </thead> <#list JSON.customers as item> <tr> <td>${‌item.firstName}</td> <td>${‌item.lastName}</td> <td>${‌item.language}</td> </tr> </#list> </table> </#if>
<!-- End JSON Part --> <!-- Saved Search Part --> <#if SEARCH?has_content> <p style="color: green"> Saved Search results: </p> <table style="width: 100%; margin-top: 10px;"> <thead> <tr> <th>trandate</th> <th>amount</th> <th>entity</th> </tr> </thead> <#list SEARCH as item> <tr> <td>${‌item.trandate}</td> <td>${‌item.amount}</td> <td>${‌item.entity}</td> </tr> </#list> </table> </#if>
<!-- End Saved Search Part --> </body>
</pdf> 

        

The SuiteScript file incorporates the JSON object and XML file with NetSuite data and the advanced template.

          /** *
@NApiVersion 2.x */
require(['N/render', 'N/file', 'N/record', 'N/search'], function(render, file, record, search) { // load JSON file from file cabinet var jsonFile = file.load({ id: #json_content_file_cabinet_id# }); // load XML file from file cabinet var xmlFile = file.load({ id: #xml_content_file_cabinet_id# }); // load printing template file from cabinet var templateFile = file.load({ id: #template_content_file_cabinet_id# }); var renderer = render.create(); renderer.templateContent = templateFile.getContents(); // add JSON custom data source renderer.addCustomDataSource({ alias: "JSON", format: render.DataSource.JSON, data: jsonFile.getContents() }); // add XML custom data source renderer.addCustomDataSource({ alias: "XML", format: render.DataSource.XML_STRING, data: xmlFile.getContents() }); // add search data source var rs = search.create({ type: search.Type.TRANSACTION, columns: ['trandate', 'amount', 'entity'], filters: [] }).run(); var results = rs.getRange(0, 1000); renderer.addSearchResults({ templateName: 'SEARCH', searchResult: results }); // add record data source var objRecord = record.create({ type: record.Type.SALES_ORDER }); renderer.addRecord({ templateName: 'record', record: objRecord }); // render PDF file and save var invoicePdf = renderer.renderAsPdf(); invoicePdf.folder = #file_cabinet_folder_id#; var id = invoicePdf.save(); }); 

        

The output of this example resembles the following.

Sample Sales Order PDF output.

Related Topics

Using Custom Data Sources for Advanced Printing

General Notices