How to Convert JSON to PDF with JavaScript in NodeJS
This NodeJS walkthrough uses JavaScript to convert a JSON file through the pdfRest Convert to PDF API Tool. One multipart request supplies the source and structured options for a tagged PDF with a clear nested layout.
Why Convert JSON to PDF with JavaScript in NodeJS?
NodeJS applications routinely receive webhook payloads and API responses that are meaningful to the product but hard to share outside a developer console. Customer-facing and operational workflows often need a stable artifact that can be downloaded, forwarded, and reviewed with other documents.
Imagine a SaaS support system investigating a failed provisioning webhook. Its backend can convert the captured JSON into a PDF that groups account fields, status details, and nested error objects hierarchically. The support engineer gains a readable case attachment, while the exact JSON remains available in the event store.
The same JavaScript integration can request source mode when braces, arrays, and literal values must remain visible. Because both presentations use /pdf, the application can choose according to the audience rather than building separate browser and server rendering paths.
JavaScript Code Example for Converting JSON to PDF
var axios = require("axios");
var fs = require("fs");
var FormData = require("form-data");
// By default, we use the US-based API service. This is the primary endpoint for global use.
var apiUrl = "https://api.pdfrest.com";
/* For GDPR compliance and enhanced performance for European users, you can switch to the EU-based service by uncommenting the URL below.
* For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
*/
//var apiUrl = "https://eu-api.pdfrest.com";
// This sample converts JSON input to a tagged PDF through multipart /pdf.
// It demonstrates structured_text_options and the format-specific conversion options.
var inputPath = "/path/to/sample.json";
var form = new FormData();
form.append("file", fs.createReadStream(inputPath));
form.append("structured_text_options", JSON.stringify({"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"data_presentation":"hierarchy"}));
form.append("output", "pdf_from_json");
axios.post(apiUrl + "/pdf", form, { headers: { "Api-Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ...form.getHeaders() }, maxBodyLength: Infinity })
.then((response) => { console.log(JSON.stringify(response.data, null, 2)); })
.catch((error) => { console.error(error.response ? error.response.data : error.message); process.exitCode = 1; });
Source: View the sample on GitHub
Breaking Down the Code
The NodeJS JSON walkthrough uses axios, form-data, and Node’s file-system module. Outside the samples project, install its HTTP and multipart dependencies with npm install axios form-data.
var axios = require("axios");
var fs = require("fs");
var FormData = require("form-data");
This NodeJS excerpt keeps the regional endpoint visible for the JSON workflow:
// By default, we use the US-based API service. This is the primary endpoint for global use. var apiUrl = "https://api.pdfrest.com"; /* For GDPR compliance and enhanced performance for European users, you can switch to the EU-based service by uncommenting the URL below. * For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work */ //var apiUrl = "https://eu-api.pdfrest.com";
JavaScript streams the .json source into the form while preserving its filename. pdfRest infers JSON conversion from that extension, so structured_text_options does not need an input_format property.
// It demonstrates structured_text_options and the format-specific conversion options. var inputPath = "/path/to/sample.json"; var form = new FormData();
The object passed through JSON.stringify is interpreted by pdfRest as structured_text_options. It sets PDF metadata, explicitly enables tagging, defines Letter portrait geometry and margins, and supplies the font and color choices used when laying out the JSON content.
{
"data_presentation": "hierarchy"
}
source is the default. It validates and parses the input, then pretty-prints normalized JSON syntax in a code-style block; original indentation and insignificant whitespace are not preserved. hierarchy removes the syntax and creates a nested list in which property names are bold and primitive values appear as key-value items.
Scalar arrays become ordinary nested values. Arrays containing objects or other arrays label their members Item 1, Item 2, and so on. The converter preserves JSON structure but intentionally does not infer application-specific report meaning. Malformed JSON is rejected in either presentation mode.
The sample’s shared style.table object does not affect JSON source or hierarchy output. It can be omitted when the profile is used only for JSON conversion.
NodeJS uses FormData to append the JSON file, stringified structured_text_options, and output name. The generated form headers provide the multipart boundary for those fields.
var inputPath = "/path/to/sample.json";
var form = new FormData();
form.append("file", fs.createReadStream(inputPath));
form.append("structured_text_options", JSON.stringify({"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"data_presentation":"hierarchy"}));
form.append("output", "pdf_from_json");
axios.post(apiUrl + "/pdf", form, { headers: { "Api-Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ...form.getHeaders() }, maxBodyLength: Infinity })
.then((response) => { console.log(JSON.stringify(response.data, null, 2)); })
.catch((error) => { console.error(error.response ? error.response.data : error.message); process.exitCode = 1; });
Axios sends the JSON request to /pdf with the form headers and Api-Key. Its success path prints resource JSON, while the rejection path exposes either the API response or the client-side error.
form.append("file", fs.createReadStream(inputPath));
form.append("structured_text_options", JSON.stringify({"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"data_presentation":"hierarchy"}));
form.append("output", "pdf_from_json");
axios.post(apiUrl + "/pdf", form, { headers: { "Api-Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ...form.getHeaders() }, maxBodyLength: Infinity })
.then((response) => { console.log(JSON.stringify(response.data, null, 2)); })
.catch((error) => { console.error(error.response ? error.response.data : error.message); process.exitCode = 1; });
Beyond the Tutorial
Useful extensions include webhook archives, account snapshots, job-result exports, and downloadable API diagnostics. Hierarchy presentation favors quick comprehension; source presentation favors developers comparing the normalized payload with code or logs.
Logical tags can improve navigation and automated interpretation without guaranteeing compliance with a named accessibility standard. Prototype the conversion in API Lab and reference the Convert to PDF documentation before finalizing production behavior.