使用 JavaScript (Node.js) 生成 PDF 报告:Puppeteer、PDFKit、jsPDF
创建 PDF 文档是 Web 开发中最常见的任务之一。报告、发票、证书、文档——所有这些都需要一个可靠的服务器端文件生成工具。在 Node.js 生态系统中,有几个强大的库,每个库都以自己的方式解决这个问题。在本文中,我们将讨论三种主要方法:通过 Puppeteer 模拟浏览器、通过 PDFKit 进行底层 PDF 操作,以及客户端-服务器解决方案 jsPDF。
1. Puppeteer — 从 HTML/CSS 生成 PDF
Puppeteer 是一个用于控制无头 Chromium 浏览器的库。它允许您加载任何 HTML 页面,应用样式,并将其“拍照”为 PDF。如果您已经拥有基于 HTML/CSS 的报告布局,并且希望精确地将其转换为 PDF,那么这是理想的选择。
主要功能:
- 支持所有 CSS 属性(Flexbox、Grid、字体、阴影)。
- 与页面上的 JavaScript 交互(Chart.js 图表、动态表格)。
- 配置纸张大小、边距、页眉页脚、背景。
- 支持自定义字体(TTF、OTF)。
报告生成示例:
const puppeteer = require('puppeteer');
async function generateReport() { const browser = await puppeteer.launch(); const page = await browser.newPage();
// 直接加载 HTML(或通过 URL) await page.setContent(` <html> <head> <style> body { font-family: Arial; padding: 40px; } h1 { color: #2c3e50; } .data { background: #ecf0f1; padding: 20px; } </style> </head> <body> <h1>销售报告</h1> <div class="data"> <p>收入:1,200,000 卢布</p> <p>订单数量:345</p> </div> </body> </html> `, { waitUntil: 'networkidle0' });
await page.pdf({ path: 'report.pdf', format: 'A4', printBackground: true, margin: { top: '20mm', bottom: '20mm' } });
await browser.close(); console.log('PDF 已创建!');}
generateReport();优点:布局精确,支持复杂布局,可与图表交互。
缺点:内存消耗高(Chromium 约 200 MB),启动速度慢。
2. PDFKit — 底层创建 PDF
PDFKit 是一个用于直接操作 PDF 结构的库。您不使用 HTML,而是以编程方式构建文档:绘制线条、添加文本、插入图像。这使您可以完全控制文档的每个像素。
主要功能:
- 矢量图形(线条、矩形、曲线)。
- 支持 Unicode 和嵌入字体。
- 创建表格、页码。
- 处理注释和链接。
创建简单发票的示例:
const PDFDocument = require('pdfkit');const fs = require('fs');
const doc = new PDFDocument({ size: 'A4', margin: 50 });doc.pipe(fs.createWriteStream('invoice.pdf'));
// 标题doc.fontSize(24).text('发票编号 12345', { align: 'center' });doc.moveDown();
// 表格(手动)doc.fontSize(12).text('名称', 50, 150);doc.text('数量', 350, 150);doc.text('价格', 450, 150);
doc.moveTo(50, 170).lineTo(550, 170).stroke();
doc.text('开发服务', 50, 180);doc.text('1', 350, 180);doc.text('150,000 卢布', 450, 180);
doc.moveDown(2);doc.fontSize(16).text('总计:150,000 卢布',