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

CustomerOps Team
ReferenceRPT-2026-W24
Date2026-06-16
Rows2
POST /v1/render

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.

Points cles

  • 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.

Ressources associees

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.

Ressources associees

Livrez plus vite avec une API orientee templates

Testez vos templates dans le playground, puis reutilisez la meme requete en production.