基于 Node.js 的 HTML 转 PDF 几种实现方案
随着 Web 技术的发展,有很多需要将 HTML 内容转换为 PDF 文档并下载的场景,比如常见的收据、发票、电子报告、对账清单、文档翻译等等。
本文将研究当前比较流行的基于 Node.js 技术栈的 HTML 转 PDF 库:Puppeteer、jsPDF 和 PDFKit,大纲如下:
Puppeteer 及优缺点 jsPDF 及优缺点 PDFKit 及优缺点 Puppeteer vs jsPDF vs PDFKit 功能对比
1.Puppeteer
1.1.使用 Puppeteer 生成 PDF
Puppeteer 是谷歌开发的一个 Node.js 库,为控制无头(或完整)Chrome 或 Chromium 浏览器提供了一个高级 API。它是最流行的开源 HTML 到 PDF 转换器,支持 HTML、CSS 和 JavaScript。
Puppeteer 允许您自动化Web浏览器中的各种任务,例如 Web 抓取、网站测试、截图创建和 PDF 生成。它利用 Chrome 或 Chromium Web 浏览器的功能将 HTML 内容呈现为 PDF 文件。
下面使用 Puppeteer 快速初始化一个项目:
nvm use 20.6.1
mkdir puppeteer-demo
cd puppeteer-demo
npm init -y
npm install puppeteer
touch index.js
在 index.js
中添加如下代码:
import puppeteer from 'puppeteer';
(async () => {
const browser = await puppeteer.launch({
headless: 'new',
});
const page = await browser.newPage();
await page.setContent(
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
body {
display: grid;
place-items: center;
margin: 0;
background-color: #ccc;
min-height: 100vh;
}
</style>
<h1>Hello, Puppeteer!</h1>
</body>
</html>`
);
await page.pdf({ path: 'result.pdf', format: 'A4' });
await browser.close();
})();
在上面的代码中,我们导入 Puppeteer 库,启动无头 Chromium 浏览器,并在浏览器中创建一个新页面。我们还会根据页面内容和指定选项(如路径和格式)生成 PDF,生成完成后关闭浏览器并释放资源。
1.2.优点
您可以完全控制要在 PDF 中包含网页的哪些部分。您可以指定具体的元素、部分或整个页面 Puppeteer 提供了自定义选项,如指定页面大小、边距、页眉和页脚,使您可以根据特定需求定制 PDF 布局 Puppeteer 可以捕捉 PDF 中的交互元素,如超链接和表单字段,适用于生成交互式 PDF 文件。
1.3.缺点
使用 Puppeteer 生成的 PDF 有时可能比使用类似库生成的PDF要大。这会影响下载时间和存储成本。 使用 Puppeteer 渲染复杂或大型网页可能会消耗资源,导致PDF生成变慢和内存使用增加。
2.PDFKit
PDFKit 是 JavaScript 生态系统中最古老和最成熟的 PDF库 之一。目前仍得到良好维护并定期更新。该库通常使用 Node.js 在服务器端环境中创建和操作 PDF 文档。它允许您通过定义每个页面的内容、布局和格式来以程序方式生成PDF文件。
PDFKit 提供了用于 PDF 文档生成的高级 API,并支持各种功能,使其成为创建自定义 PDF 的多功能工具。作为 PDFKit 的包装器,已开发出多个 PDF 库,支持自定义字体和图像嵌入。
2.1.使用 PDFKit 生成 PDF
让我们来快速初始化一个 PDFKit 项目:
nvm use 20.6.1
mkdir pdfkit-demo
cd pdfkit-demo
npm init -y
npm install pdfkit
touch index.js
在 index.js
中添加如下代码:
import fs from 'node:fs';
import PDFDocument from 'pdfkit';
const doc = new PDFDocument();
const stream = fs.createWriteStream('example.pdf');
doc.pipe(stream);
doc.fontSize(12).text('Hello, PDFKit!', { align: 'center' });
doc.end();
stream.on('finish', () => {
console.log('success');
});
执行 node index.js
后,可以看到 PDF 可以生成生成,并触发 finish
事件的回调函数执行,打印出了 success
。
2.2.优点
由于它是开源的,并由社区积极维护,PDFkit 可以不断改进和更新 PDFKit 可对 PDF 文档的内容、布局和格式进行精细控制。您可以根据自己的特定需求创建高度定制的 PDF 文档 PDFKit 是根据用户请求、数据或其他服务器端进程动态生成 PDF 的绝佳选择
2.3.缺点
创建具有高级布局和功能的复杂 PDF 可能具有挑战性,可能需要充分了解库的 API 对于新手来说,PDFKit 的学习曲线可能比更直接的 HTML 到 PDF 转换工具更陡峭,因为它需要对文档结构进行更多的手动控制
3.jsPDF
jsPDF 是一个流行的 JavaScript PDF 生成器,允许用户动态在 Web 浏览器中生成 PDF 文件。这个库维护良好,稳定易用,并且有丰富的文档。
jsPDF 在客户端操作,非常适合在 Web 应用程序中生成 PDF ,无需在服务器端生成。它可以修改现有布局,并允许用户通过自定义来控制他们的 PDF。还可以用来编辑现有的 PDF 文档或从头创建一个,包括图像、表格和形状等内容。
3.1.使用 jsPDF 生成 PDF
示例中使用官方提供的 CDN 地址 https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
</head>
<body>
<style>
body {
display: grid;
place-items: center;
margin: 0;
background-color: #ccc;
min-height: 100vh;
}
</style>
<h1>Hello, jsPDF!</h1>
<script>
document.addEventListener("DOMContentLoaded", function () {
const pdf = new window.jsPDF();
const element = document.body;
pdf.html(element, {
callback: function (pdf) {
// Save the PDF to a file or display it
pdf.save("output.pdf");
},
});
});
</script>
</body>
</html>
文档地址:http://raw.githack.com/MrRio/jsPDF/master/docs/index.html
3.2.优点
jsPDF 完全在客户端(页面)上运行,这使它成为在 Web 应用程序中生成 PDF 的一个很好的选择,而无需外部服务 jsPDF 相对易于使用,尤其是对于基本的 PDF 生成任务。您只需几行 JavaScript 代码即可创建 PDF 文档 由于 jsPDF 是一个 JavaScript 库,它可以与 Web 应用程序无缝集成,并可以与其他 JavaScript 库和框架一起使用
3.3.缺点
在客户端生成 PDF 可能会耗费大量资源,尤其是大型或复杂文档。这会影响浏览器性能或导致内存消耗问题 jsPDF 在现代 Web 浏览器中得到广泛支持,但在旧的浏览器或具有较少 JavaScript 支持的环境中可能无法按预期工作 与 PDFKit 等服务器端 PDF 生成库不同,jsPDF 具有有限的高级功能和能力。它可能不适用于复杂的PDF要求。
4.Puppeteer、jsPDF 和 PDFKit 功能比较
为便于大家参考,下面总结了 Puppeteer、jsPDF 和 PDFKit 库在 PDF 生成、文件大小、浏览器集成和社区支持方面的比较:
Puppeteer | jsPDF | PDFKit | |
---|---|---|---|
PDF生成 | 从 HTML 和网页内容生成 PDF | 从 HTML 和 SVG 内容生成 PDF | 从头开始创建 PDF |
文件大小 | 无法控制 PDF 大小 | 无法控制 PDF 大小 | 提供对 PDF 文件大小的控制 |
浏览器集成 | 为网页渲染提供无头 Chrome 集成 | 没有浏览器集成 | 没有浏览器集成 |
社区支持和更新 | 活跃的社区支持和更新 | 活跃的社区支持和更新 | 活跃的社区支持和更新 |
5.结论
当为 HTML 转 PDF 需求选择实现方案时,可以参考以上实现方案。如果你想从头开始生成 PDF,PDFKit 可能是你最好的选择。要通过 HTML 或者 SVG 内容快速转换为 PDF,jsPDF 可能更合适。对应网页渲染和交互式内容,强烈建议你选择 Puppeteer。
最后,方案选择在很大程度上还取决于你的项目类型、规范及开发者个人喜好。
大家都在看