PDF engine for AV6 to create dynamic pdf from configure json
npm install av6-pdf-engineav6-pdf-engine is a JSON-driven PDF layout engine built on top of PDFKit.
Describe your document once (page setup, styles, headers, blocks, tables, QR/barcodes, signatures, etc.) and render it to a file or in-memory buffer from any Node.js service.
- JSON definition that mirrors pdfmake-style blocks while staying close to raw PDFKit features.
- Built-in layout helpers for headers, footers, watermarks, page backgrounds, and signature flows.
- Rich block catalog: text, columns, tables, key/value grids, images, QR codes, 1D barcodes, lines, and explicit page breaks.
- Automatic asset normalization for remote URLs, Buffers, or local paths (images, QR, barcode payloads).
- Custom font registration plus reusable style definitions with full TypeScript types.
- Two rendering targets: renderCustomPdf(def, "/tmp/doc.pdf") or renderCustomPdfToBuffer(def) for HTTP responses/storage.
``bash`
npm install av6-pdf-engineor
pnpm add av6-pdf-engineor
yarn add av6-pdf-engine
`ts
import { renderCustomPdfToBuffer, renderCustomPdf, CustomDocDefinition } from "av6-pdf-engine";
const doc: CustomDocDefinition = {
pageSize: "A4",
margins: { top: 80, right: 40, bottom: 80, left: 40 },
fonts: [{ name: "Inter", src: "./assets/Inter-Regular.ttf" }],
styles: {
heading: { font: "Helvetica-Bold", fontSize: 16 },
label: { color: "#999", fontSize: 9, bold: true },
},
header: {
blocks: [{ type: "text", text: "ACME Corp — Invoice", style: "heading" }],
backgroundColor: "#f7f7f7",
},
footer: (page, size) => ({
blocks: [
{
type: "text",
text: Page ${page} / ${Math.round(size.height)},
align: "center",
},
],
}),
pageBackground: { src: "./assets/background.png", opacity: 0.05 },
watermark: { text: "ACME CONFIDENTIAL", mode: "exceptFirst", opacity: 0.1 },
content: [
{
type: "columns",
widths: [200, "*"],
columns: [
[
{ type: "text", text: "Invoice #1234", style: "heading" },
{
type: "keyValueGrid",
columns: [
[
{ key: "Issued", value: "2025-12-01" },
{ key: "Due", value: "2025-12-15" },
],
],
keyStyle: "label",
},
],
[
{
type: "table",
widths: ["*", 80, 80],
headerRows: 1,
body: [
[
{ text: "Item", style: "label" },
{ text: "Qty", style: "label", align: "right" },
{ text: "Total", style: "label", align: "right" },
],
[{ text: "Consulting" }, { text: "12", align: "right" }, { text: "$3,000", align: "right" }],
],
},
],
],
},
{ type: "qr", value: "https://acme.example.com/pay/1234", size: 80 },
{ type: "barcode", value: "123456789012", bcType: "EAN13", width: 200 },
{ type: "signature", height: 100, label: "Authorized signature" },
],
};
// Write directly to disk
await renderCustomPdf(doc, "./tmp/invoice.pdf");
// Or capture an in-memory Buffer (perfect for HTTP responses / uploads)
const pdfBuffer = await renderCustomPdfToBuffer(doc);
`
- pageSize: Any PDFKit-supported size ("A4", "LETTER", [width, height], etc.). Defaults to A4.margins
- : Required { top, right, bottom, left }. top/bottom double as header/footer bands.fonts
- : Optional array of { name, src } for custom TTF/OTF registration before rendering.header
- / footer: Structured block arrays. Footers can also be a single block, array, or a callback (pageNumber, pageSize) => Block | FooterDef.pageBackground
- : Optional image (path, URL, or Buffer) painted before content each page.watermark
- : Text watermark with opacity, angle, font size, color, and placement mode (all, first, last, exceptFirst, etc.).styles
- : Named StyleDef map that can be referenced via style on text/table cells/key-value items.content
- : Ordered array of Block objects (see below) rendered top to bottom with automatic pagination.
- text: Paragraph with typography controls (alignment, inline styles, links, margins).image
- : Local path, Buffer, or remote URL (auto-downloaded) with sizing/alignment.qr
- : QR codes via qrcode with size, version, and error correction level support.barcode
- : CODE128, EAN13, CODE39, ITF, CODE93 via bwip-js, including rotation, scaling, and caption text.columns
- : Multi-column layouts (widths, gaps, keepTogether) that can nest any other blocks.table
- : Simple table primitive with header rows, cell styles, and optional border layout hints.keyValueGrid
- : Responsive key/value pairs with shared or per-row styles, separators, and column widths.line
- : Horizontal rule with configurable width, color, and surrounding margins.pageBreak
- : Forces the renderer to finish the current page before continuing.signature
- : Reserves space (height/width) and optionally renders nested blocks or an image to support wet/digital signatures.
Each block supports a visible flag so you can skip rendering without mutating arrays.
- Images, QR payloads, and barcodes accept paths, Buffers, or HTTPS URLs. Remote sources are fetched and cached as Buffers before rendering begins.
- Nested structures (columns, signature blocks, headers/footers) are traversed automatically, so you can reference assets anywhere in the tree.
- When using remote assets, ensure your runtime has outbound network access and consider wrapping renderCustomPdf* in your own caching layer.
- Headers render inside the top margin band; footers render inside the bottom band. Adjust marginTop/marginBottom on header/footer defs for fine-grained spacing.pageBackground
- is painted before header/content on every new page, while watermark.mode decides which pages receive the overlay.(pageNumber, pageSize)
- Footer callbacks receive so you can display pagination, print timestamps, or conditionally hide content.
MIT — see LICENSE` (provide your own if distributing).