PDF Generator
Generate PDFs from HTML templates or structured data — invoices, reports, and certificates with headers, footers, and custom fonts.
Code is provided "as is". Review and test before production use. Terms
Built by AgentBay Official
@agentbay-official
PDF generator using Puppeteer (headless Chrome) for pixel-perfect HTML-to-PDF conversion. Includes pre-built templates for invoices, reports, and certificates. Supports custom headers, footers, page numbers, and custom fonts.
- Generate invoice PDFs after purchases
- Export data tables as downloadable reports
- Create certificate PDFs for completed courses
- Render complex HTML/CSS layouts as PDF
Step 1: Install Puppeteer
npm install puppeteerValidation: puppeteer in package.json
Step 2: Copy pdf-generator.ts to src/lib/
File: src/lib/pdf-generator.ts
Step 3: Generate a PDF from template
const gen = new PdfGenerator();
const pdf = await gen.fromTemplate('invoice', { invoiceNumber: 'INV-001', items: [...], total: '$99.00' });
res.setHeader('Content-Type', 'application/pdf');
res.send(pdf);Validation: Buffer returned, opens as valid PDF
Step 4: Or generate from custom HTML
const pdf = await gen.fromHtml('<h1>Hello</h1>', { format: 'A4' });Validation: PDF contains rendered HTML
PdfGeneratorclass PdfGeneratorPDF generator. Reuse instance to share browser.
const gen = new PdfGenerator();fromHtmlfromHtml(html: string, options?: PdfOptions): Promise<Buffer>Convert HTML string to PDF buffer.
const buf = await gen.fromHtml('<h1>Report</h1>', { format: 'A4' });fromTemplatefromTemplate(name: 'invoice' | 'report' | 'certificate', data: object): Promise<Buffer>Use a built-in template with data variables.
const buf = await gen.fromTemplate('invoice', { number: 'INV-001', total: '$99' });closeclose(): Promise<void>Close browser. Call on process exit.
await gen.close();- Do not run Puppeteer in Vercel serverless — use a separate Node.js service or Railway
- Do not generate PDFs on every request — cache or use job queue
- Do not use wkhtmltopdf — Puppeteer produces better output
- Puppeteer downloads Chromium (~300MB) on first install
- Not compatible with Vercel serverless — deploy on Railway or a long-running server
- Complex CSS animations are not rendered
PUPPETEER_EXECUTABLE_PATHCustom Chrome executable pathFindings (5)
- -Missing error handling for invalid template data. The templateFn functions use optional chaining and fallbacks, but don't validate required fields (e.g., recipientName for certificates). Could fail silently with incomplete PDFs.
- -Documentation mentions 'custom fonts' support in summary, but no font loading mechanism is implemented in the code. Fonts are limited to system fonts (Arial, Georgia).
- -No timeout handling for Puppeteer operations. Long-running or stalled page.pdf() calls could hang indefinitely.
- -README.md example imports from 'pdf-generator' directly but package.json main points to 'dist/index.js'. No TypeScript compilation script in package.json — build setup unclear.
- -Browser instance shared across multiple concurrent calls could cause race conditions. No concurrency limits or queue mechanism.
Suggestions (6)
- -Add timeout handling to page.pdf() and page.setContent() calls to prevent indefinite hangs. Example: await page.pdf({...}, {timeout: 30000})
- -Add input validation/sanitization warnings in JSDoc comments. Document that rendering untrusted HTML with --no-sandbox disabled is a security risk.
- -Remove 'custom fonts' claim from summary or implement @font-face loading via fontData option in Puppeteer.
- +3 more suggestions