html怎样分离资源转pdf_分离资html转pdf法【方法】

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 不需要内联,但仅支持部分属性(如 marginfontSize),不支持伪类或媒体查询
  • 适合服务端渲染场景,避免前端 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"