浏览器直接打印易出现样式错乱、分页失控、中文乱码三类问题,根源在于渲染流程与字体链失控;应先用chrome devtools模拟print媒体类型调试,再输出pdf,并确保中文字体嵌入、js执行延迟充足、避免截图式转换。

直接用浏览器打印功能最省事,但样式错乱、分页失控、中文乱码这三类问题几乎必然出现——别信“一键转换”的宣传,关键在控制渲染流程和字体链。
Chrome DevTools 里模拟 PDF 渲染再打印
很多开发者跳过这步,直接 Ctrl+P → Save as PDF,结果表格被截断、CSS Grid 布局塌陷、@media print 样式没生效。实际该先打开 DevTools(F12),切到 Rendering 面板,勾选 Emulate CSS media type 并设为 print,实时看页面如何被重排。这时能立刻发现:display: flex 在 print 模式下兼容性差、position: fixed 元素消失、背景图默认不打印(需加 -webkit-print-color-adjust: exact)。
验证无误后,再用 Chrome 的打印对话框输出 PDF,比盲打靠谱得多。
中文乱码?检查 font-family 和字体嵌入路径
PDF 不像浏览器有系统字体回退机制。用 pdfkit 或 wkhtmltopdf 时,如果 HTML 中写的是 font-family: "Microsoft YaHei", sans-serif,而生成环境没装雅黑字体,就会 fallback 到空白方块。解决方式不是换字体名,而是:
- 明确指定中文字体文件路径,比如
fontProvider.addFont("/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc") - 在 CSS 中强制用
@font-face引入,并确保src是绝对路径或 base64 内联 - 避免依赖
system-ui或未声明的字体族,PDF 渲染器不认识这些别名
wkhtmltopdf 的 --no-stop-slow-scripts 必须关掉
默认开启这个参数会导致 JS 执行中途被杀,尤其影响动态渲染内容(如 ECharts 图表、Vue 组件挂载)。现象是 PDF 里只有一片空白或 loading 状态。正确做法是显式传参:wkhtmltopdf --no-stop-slow-scripts --javascript-delay 2000 input.html output.pdf,其中 --javascript-delay 给足 JS 渲染时间,数值按实际 DOM 就绪耗时调整(可先用 console.time 测一下)。
复杂布局建议用 iText7 + pdfHTML 而非 html2canvas
html2canvas + jsPDF 本质是截图拼接,放大失真、无法选中文本、搜索不可用、文件体积大。而 iText7/pdfHTML 是真 DOM 解析 + PDF 元素树映射,支持分页控制(page-break-inside: avoid)、页眉页脚注入、书签生成。但注意它不执行 JS,所以带 Vue/React 的 SPA 页面得先服务端渲染(SSR)或预生成静态 HTML 再喂给 pdfHTML。
真正卡住人的从来不是“怎么转”,而是“转完能不能当正式交付物用”——字体嵌入是否完整、分页是否可控、文本是否可复制、超链接是否保留。这些细节不提前验证,上线后改一次 PDF 生成逻辑,往往比重写半个页面还费劲。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











