使用 TypeScript 生成 PDF 报告:PDF-Lib 库

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

使用 PDF-Lib 库在 TypeScript 中生成 PDF 报告



在现代 Web 开发中,经常需要创建复杂的 PDF 文档:报告、发票、证书或分析仪表板。TypeScript 凭借其严格的类型检查,使这一过程变得可靠且可预测。在 Node.js 平台和浏览器中众多用于处理 PDF 的库中,PDF-Lib 脱颖而出——它是一个轻量级、功能强大且完全用 TypeScript 编写的工具。



PDF-Lib 无需安装额外的原生依赖项(与 Puppeteer 或 wkhtmltopdf 等重量级解决方案不同),既可在 Node.js 中运行,也可在浏览器中运行,并支持所有现代 PDF 功能:嵌入字体、图像、创建表单、注释等。



安装与第一个文档



开始使用只需通过 npm 安装该包:



npm install pdf-lib


让我们创建一个包含文本的简单 PDF 文档:



import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';

async function createSimplePdf() { // 创建一个新的 PDF 文档 const pdfDoc = await PDFDocument.create();

// 添加一页(A4 格式) const page = pdfDoc.addPage([595.28, 841.89]); // A4 尺寸(点)

// 嵌入标准字体 const font = await pdfDoc.embedFont(StandardFonts.Helvetica);

// 绘制文本 page.drawText('你好,世界!', { x: 50, y: 700, size: 30, font: font, color: rgb(0.2, 0.4, 0.8), });

// 将文档保存为字节 const pdfBytes = await pdfDoc.save(); return pdfBytes;}

// 使用示例createSimplePdf().then((bytes) => { // 在 Node.js 中可以写入文件 // require('fs').writeFileSync('hello.pdf', bytes); console.log('PDF 已创建!大小:', bytes.length, '字节');});


处理俄语文本与自定义字体



生成俄语报告时的关键任务之一是正确显示西里尔字母。标准 PDF 字体(Helvetica、Times、Courier)不包含西里尔字符。解决方案是嵌入支持 Unicode 的 TrueType 字体。



import { PDFDocument, rgb } from 'pdf-lib';import fontkit from '@pdf-lib/fontkit';import fs from 'fs';

async function createRussianPdf() { const pdfDoc = await PDFDocument.create();

// 注册 fontkit 以使用自定义字体 pdfDoc.registerFontkit(fontkit);

// 加载包含西里尔字符的字体(例如 Roboto) const fontBytes = fs.readFileSync('Roboto-Regular.ttf'); const customFont = await pdfDoc.embedFont(fontBytes);

const page = pdfDoc.addPage([595.28, 841.89]);

page.drawText('在 TypeScript 中生成报告', { x: 50, y: 750, size: 24, font: customFont, color: rgb(0, 0, 0), });

page.drawText('日期:2024-01-15', { x: 50, y: 700, size: 14, font: customFont, color: rgb(0.3, 0.3, 0.3), });

return await pdfDoc.save();}


创建表格与结构化报告



PDF-Lib 没有内置的表格模块,但可以通过绘制线条和定位文本来手动轻松实现。为了方便,可以创建一个辅助函数:



interface TableCell {  text: string;  width: number;  height?: number;  align?: 'left' | 'center' | 'right';}

async function drawTable( page: PDFPage, headers: TableCell[], rows: TableCell[][], startX: number, startY: number, font: PDFFont, fontSize: number = 12) { const cellPadding = 5; const rowHeight = fontSize + 2 * cellPadding; let currentY = startY;

// 绘制表头 let currentX = startX; for (const header of headers) { page.drawRectangle({ x: currentX, y: currentY - rowHeight, width: header.width, height: rowHeight, color: rgb(0.9, 0.9, 0.9),

推荐