Puppeteer比pdfmake更适配合同场景,因其基于Chromium可精准渲染复杂布局、水印、页码及中文字体,而pdfmake在表格边框、页眉页脚、中文断行等方面存在明显缺陷。

Node生成PDF必须选对库:Puppeteer比pdfmake更适配合同场景
直接用 pdfmake 写合同容易翻车——它不支持复杂表格边框、页眉页脚动态插入、中文断行控制弱,遇到带公章扫描图或手写签名占位符就崩。而 puppeteer 基于 Chromium 渲染 HTML,能 1:1 复现浏览器里排版效果,合同里常见的多栏布局、水印、页码、字体嵌入(如「思源黑体」)全都能控。
实操建议:
- 用
npm install puppeteer安装(首次运行会自动下载 Chromium,国内可设环境变量PUPPETEER_DOWNLOAD_HOST指向淘宝镜像) - 避免全局安装
puppeteer-core,它不带浏览器二进制,本地调试易报Browser closed unexpectedly - 合同模板统一用
.html文件,内联 CSS(不要外链),字体用@font-face+ Base64 或提前放public/fonts/目录并用绝对路径引用
批量生成前必须处理好数据与模板的绑定逻辑
合同不是静态 PDF,每份要填入不同甲方名称、金额、签署日期。硬编码拼 HTML 字符串极易 XSS 和引号逃逸,handlebars 是最稳的选择——语法简单、无运行时依赖、支持条件块和循环,且社区有 handlebars-pdf 这类轻量封装。
关键点:
- 模板中用
{{partyA.name}}绑定对象字段,别用${data.partyA.name}模板字符串,后者无法做空值保护 - 金额数字必须走
{{formatCurrency amount}}这类自定义 helper,否则小数点后零会被吞(如100.00变成100) - 日期统一转为
YYYY年MM月DD日格式再传入,别让前端 JStoLocaleDateString()在服务端跑(Node 无 locale 配置时会出错)
导出 PDF 的选项稍不注意就导致打印异常
合同最终要打印盖章,puppeteer 的 page.pdf() 参数直接影响输出质量。默认参数生成的 PDF 在 A4 上内容被裁切、页边距过大、甚至文字模糊,都是常见问题。
使用一条命令部署ProbeChain Rydberg测试网代理节点。自动注册为Agent(NodeType=1),免gas,支持macOS/Linux/Windows。触发词:/r
必须显式设置:
-
format: 'A4'(别用paperWidth/paperHeight手动算,单位是英寸,易错) -
margin: { top: '20mm', right: '15mm', bottom: '20mm', left: '15mm' }(CSS 的@page { margin: ... }在 Puppeteer 中常被忽略,必须靠 API 控) -
printBackground: true(否则 CSS 背景色、水印不显示) -
preferCSSPageSize: true(让 HTML 中@page { size: A4 }生效,和上面 format 不冲突)
漏掉任意一项,PDF 在打印机上可能偏移 1cm 或第二页空白。
VSCode 里调试生成流程要绕过两个隐藏坑
在 VSCode 中直接 F5 运行 Node 脚本生成 PDF,常卡在 browser.launch() 或生成空白页。这不是代码问题,而是开发环境限制。
解决方案:
- 启动时加
headless: 'new'(旧版true在 M1/M2 Mac 上会崩溃) - Windows 用户若报
Failed to launch chrome,删掉node_modules/puppeteer/.local-chromium重装,别信网上改executablePath指向系统 Chrome 的方案——版本不匹配必报ERR_INVALID_ARGUMENT - VSCode 的
debug模式下禁用所有非必要插件(尤其「Live Server」和「Auto Rename Tag」),它们会劫持file://协议导致 HTML 模板加载失败
真正稳定的调试方式:先用 console.log(htmlString) 把渲染后的 HTML 保存为临时文件,用 VSCode 内置浏览器预览,确认样式无误再进 PDF 流程。


















