前言
官方文档
添加依赖
1 | npm install puppeteer@24.8.2 pdf-lib@1.17.1 |
其中
puppeteer把HTML转为PDFpdf-lib把封面、目录、正文的PDF进行合并
安装慢可以使用
1 | npm install -g cnpm --registry=https://registry.npmmirror.com |
puppeteer和puppeteer-core
安装puppeteer,会下载Chrome可能时间比较长。
puppeteer-core 不会自动下载 Chromium,可以结合系统中已有的 Chrome浏览器使用。
puppeteer
1 | const puppeteer = require('puppeteer'); |
puppeteer-core
1 | npm i puppeteer-core@24.8.2 |
这种初始化的时候要指定chrome.exe路径,使用edge不行。
1 | const puppeteer = require('puppeteer-core'); |
整体示例
页面样式
1 | .page { |
注意
A4是
201mm*297mm
导出脚本
1 | const puppeteer = require("puppeteer"); |
常用设置
初始化
1 | const browser = await puppeteer.launch({ |
注意
上面的参数中的
args建议添加,添加后在Docker容器中才能正常运行。并且也不影响在非容器内的运行。
加载页面
1 | await page.goto("http://localhost:5173/cover.html", { |
waitUntil的值
"load"
等待页面的load事件触发(即 HTML 文档完全加载并解析完成)。此时可能仍有图片等资源在加载。"domcontentloaded"
等待页面的DOMContentLoaded事件触发(即 HTML 解析完成,无需等待样式表、图片等资源)。"networkidle0"
等待页面网络请求数量减少到 0 个(即没有任何网络活动)并持续 500 毫秒。这是最严格的策略,确保所有资源都加载完成。"networkidle2"
如上所述,等待网络请求数量 ≤2 并持续 500 毫秒。
等待页面加载完成
等待某个元素完成渲染
1 | // 等待某个元素完成渲染 |
延迟
1 | // 延迟1秒等待动画结束 |
下面的这种方式我这测试的无效,目前还是使用第一种方法,等加载完在页面上添加一个元素。
页面状态
1 | await page.waitForFunction(() => { |
控制生成PDF区域
你可以在页面中添加一个 <div> 容器,只包含你想导出为 PDF 的内容,并通过 CSS 的 @media print 规则隐藏其他部分。
1 | <style> |
设置后可以使用打印快捷键Ctrl + P查看效果。
换页控制
在使用 Puppeteer 生成 PDF 时,如果你希望在 HTML 中某个位置强制换页(分页),可以通过 CSS 的分页控制属性来实现。这是最标准、最可靠的方式。
方法:使用 CSS page-break-* 或 break-* 属性
分页控制
现代浏览器(包括 Chromium,即 Puppeteer 使用的引擎)支持以下 CSS 属性来控制分页:
元素前换页
1 | .page-break-before { |
元素后换页
1 | .page-break-after { |
避免元素被分页打断
避免元素被分页打断(保持完整在一页)
1 | .no-break { |
注意:
推荐同时使用新标准(
break-*)和旧标准(page-break-*)以提高兼容性。
示例
1 |
|
注意事项
- 不要对行内元素(如
<span>)使用分页属性,应使用块级元素(<div>,<section>,<h1>等)。 - 如果页面有复杂布局(如 Flex/Grid),某些分页行为可能被忽略,建议测试效果。
break-*是 CSS Paged Media Module Level 3 的标准,Chromium 支持良好。
最佳实践
直接把分页类加在你希望“新开一页”的标题上:
1 | <h2 class="page-break-before">新章节标题</h2> |
脚本传参
调用脚本传参
test_para.js
1 | // 获取传入的参数 |
调用
1 | node test_para.js config=/data/test/paras.json other=show |
可以看到接收的数组
接收到的参数: [ ‘config=/data/test/paras.json’, ‘other=show’ ]
为了方便可以转为对象
1 | // 获取传入的参数 |
访问
1 | node .\index.js name="zhangsan" age=8 |
结果
接收到的参数: { name: ‘zhangsan’, age: ‘8’ }
服务器环境
在 Linux 上安装 Puppeteer 时,需要确保系统已安装必要的依赖库:
Debian/Ubuntu
1 | # 安装 Chrome 运行所需的依赖 |
CentOS/RHEL
1 | sudo yum install -y \ |
NodeJS
1 | # 安装 nvm |
Docker方式
在Linux上安装依赖和NodeJS会需要别的依赖,比较麻烦,这里提供使用Docker的方式构建
脚本
Dockerfile
1 | # 使用官方 Node.js 镜像 |
构建
1 | docker build -t puppeteer-docker . |
测试
调用容器内的JS
1 | docker run --rm puppeteer-docker node index.js |
调用Docker外的JS
1 | # CentOS下 |
复制字体
1 | cd C:\Windows\Fonts |