html2pdf.js需手动内联CSS、转图片为base64或绝对URL;pdfmake+html-to-pdfmake适合预处理HTML并映射资源;puppeteer最稳,自动加载所有资源并支持字体/SVG/表格精准渲染。

用 html2pdf.js 转 PDF 时如何分离资源(CSS/JS/图片)?
直接在浏览器中用 html2pdf.js 转 PDF,如果 HTML 里引用了外部 CSS、JS 或相对路径图片,PDF 生成常出现样式丢失、空白或报错 Failed to load resource。根本原因是:该库默认只处理内联样式和同域已加载的 DOM,不自动抓取并嵌入外部资源。
- 必须手动将关键 CSS 内联(
或),不能依赖 - JS 文件可忽略(PDF 不执行脚本),但若 JS 动态插入内容,需确保转 PDF 前 DOM 已稳定
- 图片必须为绝对 URL 或 base64;相对路径(如
./img/logo.png)在 PDF 中无法解析
为什么 pdfmake + html-to-pdfmake 更适合分离资源?
它不操作真实 DOM,而是把 HTML 字符串解析成 PDF 结构对象,天然规避跨域、加载时机问题。你完全可以先用 Node.js 或构建工具预处理 HTML:提取 CSS、转图片为 base64、移除无关标签,再传给 html-to-pdfmake。
-
html-to-pdfmake支持images选项,可传入映射表把路径替换成 base64 字符串 - CSS 不需要内联,但仅支持部分属性(如
margin、fontSize),不支持伪类或媒体查询 - 适合服务端渲染场景,避免前端 CORS 和资源加载不确定性
Node.js 后端用 puppeteer 分离资源最稳
这是目前生产环境最可靠的方案:启动无头 Chrome,完整加载 HTML 及所有资源(含字体、SVG、CDN 图片),再截图或导出 PDF。资源分离靠 Puppeteer 的 page.setContent() 或 page.goto() 自动完成,无需手动处理路径。
- 用
page.setContent(html, { waitUntil: 'networkidle0' })确保所有资源加载完毕 - 若 HTML 含本地文件路径(如
file:///),需启用--no-sandbox并注意权限限制 - 导出前可执行
page.addStyleTag({ content: 'body { margin: 0; }' })强制重置样式,避免浏览器默认样式干扰 PDF 布局
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(htmlString, { waitUntil: 'networkidle0' });
await page.pdf({ path: 'output.pdf', format: 'A4' });
await browser.close();
分离资源时最容易被忽略的三个点
不是“能不能转”,而是“转出来的 PDF 是否能复现原始排版”。以下三点一旦漏掉,PDF 就会错位、截断或字体异常:
立即学习“前端免费学习笔记(深入)”;
- Web 字体(
@font-face)必须转为 base64 内联,否则 PDF 用系统默认字体替代 - SVG 中的
引用需展开为完整,否则多数 PDF 库不识别 - 表格列宽用
%或auto在 PDF 中表现不稳定,建议统一换算为固定像素值(如width="200")











