pdf-generation

Puppeteer HTML-to-PDF (recommended for complex layouts)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "pdf-generation" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-pdf-generation

PDF Generation

Puppeteer HTML-to-PDF (recommended for complex layouts)

import puppeteer from 'puppeteer';

async function generatePdf(html: string): Promise<Buffer> { const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.setContent(html, { waitUntil: 'networkidle0' });

const pdf = await page.pdf({ format: 'A4', margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' }, printBackground: true, });

await browser.close(); return Buffer.from(pdf); }

// Express endpoint app.get('/api/invoice/:id/pdf', async (req, res) => { const invoice = await getInvoice(req.params.id); const html = renderInvoiceHtml(invoice); const pdf = await generatePdf(html); res.contentType('application/pdf'); res.setHeader('Content-Disposition', attachment; filename="invoice-${invoice.number}.pdf"); res.send(pdf); });

PDFKit (Node.js — programmatic)

import PDFDocument from 'pdfkit';

function createInvoicePdf(invoice: Invoice): Promise<Buffer> { return new Promise((resolve) => { const doc = new PDFDocument({ size: 'A4', margin: 50 }); const chunks: Buffer[] = []; doc.on('data', (chunk) => chunks.push(chunk)); doc.on('end', () => resolve(Buffer.concat(chunks)));

// Header
doc.fontSize(20).text('INVOICE', { align: 'right' });
doc.fontSize(10).text(`#${invoice.number}`, { align: 'right' });
doc.moveDown();

// Table
doc.fontSize(12).text('Item', 50, doc.y);
doc.text('Amount', 400, doc.y - 12, { width: 100, align: 'right' });
doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();

for (const item of invoice.items) {
  doc.text(item.description, 50, doc.y + 5);
  doc.text(`$${item.amount.toFixed(2)}`, 400, doc.y - 12, { width: 100, align: 'right' });
}

doc.end();

}); }

@react-pdf/renderer (React components to PDF)

import { Document, Page, Text, View, StyleSheet, renderToBuffer } from '@react-pdf/renderer';

const styles = StyleSheet.create({ page: { padding: 30 }, title: { fontSize: 24, marginBottom: 20 }, row: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 5 }, });

function InvoicePdf({ invoice }: { invoice: Invoice }) { return ( <Document> <Page size="A4" style={styles.page}> <Text style={styles.title}>Invoice #{invoice.number}</Text> {invoice.items.map((item) => ( <View key={item.id} style={styles.row}> <Text>{item.description}</Text> <Text>${item.amount.toFixed(2)}</Text> </View> ))} </Page> </Document> ); }

// Server-side render const buffer = await renderToBuffer(<InvoicePdf invoice={invoice} />);

Python (ReportLab)

from reportlab.lib.pagesizes import A4 from reportlab.platypus import SimpleDocTemplate, Table, Paragraph from reportlab.lib.styles import getSampleStyleSheet

def generate_invoice_pdf(invoice: dict, output_path: str): doc = SimpleDocTemplate(output_path, pagesize=A4) styles = getSampleStyleSheet() elements = []

elements.append(Paragraph(f"Invoice #{invoice['number']}", styles['Title']))

data = [['Item', 'Amount']]
for item in invoice['items']:
    data.append([item['description'], f"${item['amount']:.2f}"])

table = Table(data, colWidths=[350, 100])
elements.append(table)
doc.build(elements)

Anti-Patterns

Anti-Pattern Fix

New browser per PDF request Reuse browser instance, create new pages

No timeout on PDF generation Set page.setDefaultTimeout() and abort

Generating PDFs synchronously in request Use background job queue

Inline CSS in HTML templates Use embedded <style> or printBackground: true

No memory cleanup Close pages after use, limit concurrent generations

Production Checklist

  • Browser instance pooling (Puppeteer/Playwright)

  • PDF generation in background queue

  • Memory limits and timeouts configured

  • Generated PDFs stored in object storage (S3)

  • Content-Disposition header for downloads

  • PDF/A compliance if archiving required

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

webrtc

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-19

No summary provided by upstream source.

Repository SourceNeeds Review