blog
Generate Beautiful PDF Reports from JSON in Under 5 Minutes
When your PDF pipeline cracks at 2 AM and customers are waiting on invoices, debugging headless Chromium is the last thing you want to do. This guide cuts to what actually matters for generate PDF from template in production: templates that render the same way every time, render jobs that survive queue spikes, and an API surface with clear failure modes so on-call is boring.
Updated 2026-02-24
Problem
A developer needs to turn a JSON payload into a clean report without building and maintaining a custom PDF renderer.
Start with one practical template, wire JSON inputs to stable fields, and move the same payload from preview to production.
Typst playground
A developer needs to turn a JSON payload into a clean report without building and maintaining a custom PDF renderer.
Report Typst template
Sample JSON payload
#set page(paper: "a4", margin: 18mm)
#set text(font: "Inter", size: 10pt)
#let data = sys.inputs
#text(size: 22pt, weight: "bold")[#data.title]
#v(4pt)
#text(fill: rgb("#64748b"))[#data.reference + " - " + data.date]
#v(12pt)
#block(
fill: rgb("#f8fafc"),
stroke: 0.5pt + rgb("#e2e8f0"),
inset: 12pt,
radius: 4pt,
)[
#text(weight: "semibold")[#data.customer]
#linebreak()
#text(fill: rgb("#64748b"))[#data.status]
]
#v(12pt)
#table(
columns: (1fr, auto, auto),
inset: 7pt,
stroke: 0.5pt + rgb("#e2e8f0"),
[*Item*], [*Qty*], [*Amount*],
..data.line_items.map(item => (
item.name,
str(item.qty),
"$" + str(item.amount),
)).flatten(),
)Weekly report
Draft
Weekly report
Draft
Solution & copyable API code
Define the template input schema before writing layout logic. This keeps your API payload stable as the design evolves. Use published template versions in production and keep fast preview loops for authoring. This gives velocity without sacrificing change control.
const response = await fetch(`${process.env.DOCUFORGE_API_URL}/v1/render`, {
method: "POST",
headers: {
"X-API-Key": process.env.DOCUFORGE_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ template_id: "tpl_generate_beautiful_pdf_reports_from_json_in_under_5_minutes", data: payload }),
});
const pdf = Buffer.from(await response.arrayBuffer());Customization tips
- Start with the smallest layout that proves the document contract.
- Use real customer-shaped sample data before publishing a new version.
- Keep brand colors, spacing, and repeated footer copy in shared template variables.
- Pass customer-specific values through JSON data instead of forking the template.
- Store one approved sample payload per template so preview regressions are easy to catch.
Wichtigste Punkte
- Schema-first templates reduce regression risk during design edits.
- Preview loops should be fast; production renders should be repeatable.
- Small reusable template fragments beat copy-paste document blocks.
- Keep code examples close to real production payloads.
Why teams choose DocuForge for this workflow
- Template versioning and publish workflow are built into the platform.
- Playground and docs map directly to the same API render contract.
- Typed endpoints keep integration logic consistent across teams.
Verwandte Inhalte
FAQ
Should template logic include business rules?
Keep heavy business rules in backend payload preparation; templates should focus on deterministic presentation.
How do we reduce template drift over time?
Use reusable snippets, version every release, and run sample payload regression previews before publishing.
Verwandte Inhalte
Schneller liefern mit einer Template-first API
Templates live testen und dieselbe Payload direkt in Produktion verwenden.
