如何在客户端将网页HTML转为PDF?html2pdf.js 完全实战指南

文章目录

你可能会问,鼠标右键就能打印网页,为什么还要自己编程实现这种需求。我的回答是:第一,做网页永远优先考虑移动端的体验;第二,需要精细化控制生成的PDF内容,而非打印整个HTML网页。

一、html2pdf.js 项目简介

html2pdf.js 是一个纯客户端 JavaScript 库,可将任意网页或 DOM 元素转换为可打印的 PDF 文档。它基于 html2canvas(负责将 HTML 渲染为 Canvas 图像)和 jsPDF(负责将图像封装为 PDF)构建,整个转换过程完全在浏览器中完成,无需服务器参与

核心定位:html2pdf.js 本质上是一个"截图式"PDF 生成器——它将 HTML 内容先渲染为位图图像,再将图像嵌入 PDF。这意味着输出的是栅格图像而非矢量文本,文字不可选中和搜索,且文件体积较大。

html2pdf.js 基本用法示例

最简单的用法只需一行代码:

var element = document.getElementById("element-to-print");
html2pdf(element);

这将生成 #element-to-print 的 PDF 并自动触发下载。

二、html2pdf.js 安装与引入

CDN 引入(推荐)

使用 cdnjs 锁定特定版本,确保稳定性:

<script
  src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"
  integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg=="
  crossorigin="anonymous"
  referrerpolicy="no-referrer"
></script>

直接下载

下载 dist/html2pdf.bundle.min.js 到项目目录:

<script src="html2pdf.bundle.min.js"></script>

npm 安装

npm install --save html2pdf.js

注意:包名必须包含 .js 后缀,即 html2pdf.js 而非 html2pdf

Bower 安装

bower install --save html2pdf.js

浏览器控制台临时使用

若无法修改页面源码,可在浏览器控制台中动态注入:

function addScript(url) {
  var script = document.createElement("script");
  script.type = "application/javascript";
  script.src = url;
  document.head.appendChild(script);
}
addScript(
  "https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js",
);

// 注入后即可使用
html2pdf(document.body);

非打包版本依赖顺序

若使用未打包的 dist/html2pdf.min.js,必须按顺序引入依赖,否则 jsPDF 内置的 html2canvas 会覆盖独立版本:

<script src="jspdf.min.js"></script>
<script src="html2canvas.min.js"></script>
<script src="html2pdf.min.js"></script>

三、html2pdf.js 使用场景与实战案例

场景 1:发票与报表导出

这是 html2pdf.js 最典型的应用场景。将页面中的发票或报表区域导出为 PDF。

function exportInvoice() {
  const element = document.getElementById("invoice");

  const opt = {
    margin: [10, 10, 10, 10], // 上下左右边距 10mm
    filename: `invoice-${Date.now()}.pdf`,
    image: { type: "jpeg", quality: 0.98 },
    html2canvas: {
      scale: 2, // 高清输出
      useCORS: true, // 允许跨域图片
      scrollX: 0,
      scrollY: 0,
    },
    jsPDF: {
      unit: "mm",
      format: "a4",
      orientation: "portrait",
    },
    pagebreak: {
      mode: ["css", "legacy"], // 尊重 CSS 分页规则
      avoid: ".no-break", // 避免在这些元素内分页
    },
  };

  html2pdf().set(opt).from(element).save();
}

场景 2:简历 / 证书 / 合同一键下载

利用 onclone 在导出前隐藏编辑按钮、添加水印等。

function exportResume() {
  const element = document.querySelector(".resume-container");

  const opt = {
    margin: 0,
    filename: "my-resume.pdf",
    image: { type: "jpeg", quality: 0.95 },
    html2canvas: { scale: 2 },
    jsPDF: { unit: "mm", format: "a4", orientation: "portrait" },
  };

  // 使用 Worker API 在生成后添加水印
  html2pdf()
    .set(opt)
    .from(element)
    .toPdf()
    .get("pdf")
    .then(function (pdf) {
      // 在每页添加页眉/页脚
      const totalPages = pdf.internal.getNumberOfPages();
      for (let i = 1; i <= totalPages; i++) {
        pdf.setPage(i);
        pdf.setFontSize(10);
        pdf.text("Confidential - Page " + i + " of " + totalPages, 10, 287);
      }
    })
    .save();
}

场景 3:长文档分页导出(避免内容截断)

function exportLongDocument() {
  const element = document.getElementById("long-content");

  const opt = {
    margin: [15, 15, 15, 15],
    filename: "document.pdf",
    image: { type: "jpeg", quality: 0.95 },
    html2canvas: {
      scale: 2,
      windowWidth: element.scrollWidth,
      windowHeight: element.scrollHeight,
    },
    jsPDF: {
      unit: "mm",
      format: "a4",
      orientation: "portrait",
    },
    pagebreak: {
      mode: "avoid-all", // 避免任何元素被分页截断
      before: ".page-break-before", // 在指定元素前强制分页
    },
  };

  html2pdf().set(opt).from(element).save();
}

HTML 结构配合

<div id="long-content">
  <div class="section">第一部分内容...</div>
  <div class="page-break-before"></div>
  <!-- 强制分页点 -->
  <div class="section">第二部分内容...</div>
</div>

场景 4:横向布局 / 自定义页面尺寸

function exportLandscapeTable() {
  const element = document.getElementById("wide-table");

  const opt = {
    margin: [10, 10, 10, 10],
    filename: "report-landscape.pdf",
    image: { type: "jpeg", quality: 0.98 },
    html2canvas: { scale: 2 },
    jsPDF: {
      unit: "mm",
      format: [297, 210], // A4 横向:宽 297mm,高 210mm
      orientation: "landscape",
    },
  };

  html2pdf().set(opt).from(element).save();
}

场景 5:差异化导出(打印版与屏幕版不同内容)

html2pdf()
  .set({
    margin: 10,
    filename: "print-version.pdf",
  })
  .from(document.getElementById("content"))
  .toContainer()
  .then(function () {
    // 在容器生成后、Canvas 渲染前修改内容
    const doc = this.prop.container;
    const buttons = doc.querySelectorAll(".action-buttons");
    buttons.forEach((btn) => btn.remove());
  })
  .toCanvas()
  .toImg()
  .toPdf()
  .save();

四、html2pdf.js 配置选项完全解析

本节内容为你详细介绍 html2pdf.js 有哪些配置选项,以及有什么作用,如何使用。

html2pdf.js 通过可选的 opt 参数进行配置,支持新旧两种调用风格:

// 新 Promise-based 风格(推荐)
html2pdf().set(opt).from(element).save();

// 旧单体风格
html2pdf(element, opt);

4.1 顶层配置项

配置项类型默认值说明
marginnumber / array0PDF 边距(jsPDF 单位)。可为单个数字 [vMargin, hMargin][top, left, bottom, right]
filenamestring'file.pdf'导出 PDF 的默认文件名
pagebreakobject{mode: ['css', 'legacy']}分页行为控制,详见下文
imageobject{type: 'jpeg', quality: 0.95}图像类型和质量
enableLinksbooleantrue是否自动在 <a> 标签上添加 PDF 超链接
html2canvasobject{}直接传递给 html2canvas 的配置选项
jsPDFobject{}直接传递给 jsPDF 的配置选项

4.2 margin 边距配置详解

margin 支持三种格式,灵活适应不同需求:

// 格式 1:统一边距
margin: 10; // 四边均为 10(jsPDF 单位)

// 格式 2:垂直/水平边距
margin: [10, 20]; // 上下 10,左右 20

// 格式 3:四边独立
margin: [10, 15, 20, 15]; // 上 10,右 15,下 20,左 15

常见问题:边距设置不当会导致内容被截断。若出现文字或图片边缘被切掉的情况,尝试增大边距或调整 html2canvas.scale

4.3 pagebreak 分页控制详解

分页是 html2pdf.js 最复杂的配置之一,合理设置可大幅提升 PDF 质量。

分页设置项

设置项类型默认值说明
modestring / array['css', 'legacy']自动分页模式,可选 'avoid-all''css''legacy'
beforestring / array[]在匹配元素前添加分页符(CSS 选择器)
afterstring / array[]在匹配元素后添加分页符
avoidstring / array[]避免在这些元素内部分页

分页模式说明

模式说明
avoid-all自动添加分页符以避免任何元素被跨页分割
css根据 CSS break-beforebreak-afterbreak-inside 属性添加分页。仅识别 always/left/right(用于 before/after)和 avoid(用于 inside)
legacy在带有 html2pdf__page-break 类的元素后添加分页(遗留功能,未来可能移除)

分页配置示例

// 避免所有元素被分割,并在 #page2el 前强制分页
html2pdf().set({
  pagebreak: { mode: "avoid-all", before: "#page2el" },
});

// 启用所有模式
html2pdf().set({
  pagebreak: { mode: ["avoid-all", "css", "legacy"] },
});

// 仅使用显式元素控制,不启用自动模式
html2pdf().set({
  pagebreak: {
    before: ".beforeClass",
    after: ["#after1", "#after2"],
    avoid: "img",
  },
});

重要提示avoid-all 模式在 flex 布局下可能失效。若遇到分页仍截断内容的情况,确保循环元素有单一父元素包裹(避免使用 React Fragment <></>),并尝试将 mode 设为 ['css', 'legacy']

4.4 image 图像质量配置

控制从 canvas 导出到 PDF 的图像格式和质量:

配置项类型默认值说明
typestring'jpeg'图像类型,支持 'png''jpeg''webp'(Chrome 支持)
qualitynumber0.95图像质量,0 到 1 之间。仅对 jpeg/webp 有效,png 忽略此设置

质量与文件体积权衡

// 高质量(文件较大)
image: { type: 'jpeg', quality: 0.98 }

// 平衡方案
image: { type: 'jpeg', quality: 0.85 }

// 最小体积(文字可能模糊)
image: { type: 'jpeg', quality: 0.7 }

// PNG 无损(适合含透明内容,但体积大)
image: { type: 'png' }

注意:PNG 格式不支持 quality 参数。如需 PNG 压缩,可尝试 canvas-png-compression shim。

4.5 html2canvas 配置透传

html2pdf.js 将所有 html2canvas 配置项直接传递给底层 html2canvas 库。常用配置:

html2pdf().set({
  html2canvas: {
    scale: 2, // 渲染缩放比例
    useCORS: true, // 允许跨域图片
    allowTaint: false, // 不允许污染 canvas
    backgroundColor: "#ffffff", // 背景色
    logging: false, // 关闭调试日志
    windowWidth: 1200, // 模拟窗口宽度
    windowHeight: 800, // 模拟窗口高度
  },
});

4.6 jsPDF 配置透传

配置 PDF 文档本身的属性:

html2pdf().set({
  jsPDF: {
    unit: "mm", // 单位:'pt', 'mm', 'cm', 'in'
    format: "a4", // 页面格式:'a4', 'letter', 'legal' 或 [宽, 高]
    orientation: "portrait", // 方向:'portrait' 或 'landscape'
    compress: true, // 启用压缩
  },
});

常用页面格式

格式尺寸(宽 × 高,mm)
a4210 × 297
a3297 × 420
letter216 × 279
legal216 × 356
[宽, 高]自定义尺寸

五、Worker API 与高级用法

html2pdf.js 提供基于 Promise 的 Worker API,每个步骤都可配置和拦截。

5.1 默认工作流

内部强制的工作流顺序为:

.from() → .toContainer() → .toCanvas() → .toImg() → .toPdf() → .save()

5.2 Worker 方法完整列表

方法参数说明
from(src, type)src, type设置源内容。type 可选 'string''element''canvas''img'
to(target)target转换到指定目标:'container''canvas''img''pdf'
toContainer()-转换为容器(克隆 DOM)
toCanvas()-转换为 Canvas
toImg()-转换为图像
toPdf()-转换为 PDF
output(type, options, src)type, options, src根据 src'pdf''img')路由到 outputPdfoutputImg
outputPdf(type, options)type, options调用 jsPDF 的 output 方法,返回 Promise
outputImg(type, options)type, options返回图像数据。支持 'img''datauristring'/'dataurlstring''datauri'/'dataurl'
save(filename)filename保存 PDF,触发浏览器下载
set(opt)opt设置配置属性
get(key, cbk)key, cbk获取指定属性,返回 Promise 或通过回调获取
then(onFulfilled, onRejected)-标准 Promise 方法,this 重新绑定到 Worker,带进度追踪
thenCore(onFulfilled, onRejected)-标准 Promise 方法,this 重新绑定到 Worker,无进度追踪
thenExternal(onFulfilled, onRejected)-真正的 Promise 方法。使用后将退出 Worker 链,无法继续链式调用
catch(onRejected) / catchExternal(onRejected)-标准 Promise catch。catchExternal 退出 Worker 链
error(msg)msg在 Worker 的 Promise 链中抛出错误

5.3 方法别名

方法别名
savesaveAs
setusing
outputexport
thenrun

5.4 高级链式调用示例

// 基础链式
var worker = html2pdf().from(element).save();

// 中间插入自定义操作
html2pdf()
  .from(element)
  .set(opt)
  .toContainer()
  .then(function () {
    // 容器已生成,可在此修改克隆 DOM
    const container = this.prop.container;
    container.querySelector(".hide-in-pdf").style.display = "none";
  })
  .toCanvas()
  .then(function () {
    // Canvas 已生成,可获取 canvas 对象
    const canvas = this.prop.canvas;
    console.log("Canvas size:", canvas.width, "x", canvas.height);
  })
  .toImg()
  .toPdf()
  .get("pdf")
  .then(function (pdf) {
    // 获取 jsPDF 实例,添加页眉页脚
    pdf.setPage(1);
    pdf.setFontSize(20);
    pdf.text("Header", 10, 10);
  })
  .save();

5.5 获取中间产物

// 获取 canvas 对象
html2pdf()
  .from(element)
  .toCanvas()
  .then(function () {
    const canvas = this.prop.canvas;
    // 可将 canvas 用于其他用途
  });

// 获取图像 DataURL
html2pdf()
  .from(element)
  .toImg()
  .outputImg("datauristring")
  .then(function (dataUri) {
    console.log(dataUri); // data:image/jpeg;base64,...
  });

// 获取 PDF Blob
html2pdf()
  .from(element)
  .toPdf()
  .outputPdf("blob")
  .then(function (blob) {
    // 可上传到服务器
  });

六、html2pdf.js 分页问题:避免内容截断的完整方案

应该你也会遇到 html2pdf.js 的分页问题,会把一行文字从中间上下劈成两半,效果很差。

6.1 CSS 分页属性

html2pdf.js 识别以下 CSS 分页属性:

/* 在元素前强制分页 */
.page-break-before {
  break-before: always;
  page-break-before: always; /* 旧版浏览器 */
}

/* 在元素后强制分页 */
.page-break-after {
  break-after: always;
  page-break-after: always;
}

/* 避免元素内部被分页截断 */
.no-break {
  break-inside: avoid;
  page-break-inside: avoid;
}

6.2 遗留分页类

为兼容旧版本,带有 html2pdf__page-break 类的元素后会自动分页(需启用 legacy 模式):

<div>第一页内容</div>
<div class="html2pdf__page-break"></div>
<div>第二页内容</div>

6.3 Flex 布局下的分页问题

现象:使用 flex 布局时,avoid-all 模式失效,子元素仍被分页截断。

原因:html2pdf.js 在克隆 DOM 时对 flex 容器的分页计算存在 bug。

解决方案

  1. 确保循环元素有单一父元素包裹(不要用 React Fragment <></>);
  2. 改用 mode: 'css' 配合 CSS break-inside: avoid
  3. 为关键元素显式设置 avoid 选择器。
html2pdf()
  .set({
    pagebreak: {
      mode: "css",
      avoid: ".card, .table-row, .flex-item",
    },
  })
  .from(element)
  .save();
.card,
.table-row,
.flex-item {
  break-inside: avoid;
  page-break-inside: avoid;
}

6.4 页眉页脚添加

通过 toPdf().get('pdf') 获取 jsPDF 实例后,可在每页添加页眉页脚:

html2pdf()
  .from(element)
  .set(opt)
  .toPdf()
  .get("pdf")
  .then(function (pdf) {
    const totalPages = pdf.internal.getNumberOfPages();

    for (let i = 1; i <= totalPages; i++) {
      pdf.setPage(i);

      // 页眉
      pdf.setFontSize(10);
      pdf.setTextColor(100);
      pdf.text("Company Name", 10, 10);

      // 页脚
      pdf.text(`Page ${i} of ${totalPages}`, 10, 287);

      // 添加 Logo 图片
      pdf.addImage(logoBase64, "PNG", 180, 5, 20, 20);
    }
  })
  .save();

七、html2pdf.js 常见问题与解决方案

7.1 html2pdf.js 生成的 PDF 文字模糊 / 图像质量差

现象:PDF 中的文字边缘模糊,尤其是 Retina 屏幕。

原因:默认 scale 可能不足以产生高清晰度输出。

解决方案:提升 html2canvas.scale 并配合合适的图像质量。

html2pdf()
  .set({
    image: { type: "jpeg", quality: 0.98 },
    html2canvas: {
      scale: 2, // Retina 屏幕建议 2 或更高
      dpi: 192, // 可选,明确设置 DPI
    },
  })
  .from(element)
  .save();

权衡scale 提升会显著增加内存占用和生成时间,长文档建议保持在 2 以内。

7.2 html2pdf.js 跨域图片显示为空白

现象:PDF 中来自 CDN 或其他域名的图片缺失。

原因:浏览器的同源策略阻止了跨域图片的读取。

解决方案

  1. 图片服务器配置 Access-Control-Allow-Origin 响应头;
  2. 设置 html2canvas.useCORS: true
  3. <img> 标签添加 crossorigin="anonymous" 属性。
html2pdf()
  .set({
    html2canvas: {
      useCORS: true,
      allowTaint: false,
    },
  })
  .from(element)
  .save();
<img crossorigin="anonymous" src="https://cdn.example.com/image.jpg" />

7.3 html2pdf.js 自定义字体(如 Inter、阿里巴巴普惠体)未生效

现象:PDF 中使用回退字体(如 Helvetica)而非页面显示的自定义字体。

原因:html2canvas 在渲染时会重新加载字体,若字体未完全加载则使用 fallback。

解决方案

  1. 确保字体在调用 html2pdf 前已加载完成;
  2. 使用 document.fonts.ready 等待字体;
  3. 将字体转为 Base64 内联。
await document.fonts.ready;

html2pdf()
  .set({
    html2canvas: { scale: 2 },
  })
  .from(element)
  .save();

7.4 html2pdf.js 内容被 margin 截断 / 边缘裁切

现象:设置了 margin 后,PDF 边缘的文字或图片被截断。

原因:html2canvas 渲染的 canvas 尺寸与 jsPDF 页面尺寸不匹配。

解决方案

  1. 适当增大 margin;
  2. 确保 html2canvaswidth 与元素实际宽度匹配;
  3. 检查元素是否有固定宽度超出 PDF 页面。
const opt = {
  margin: [20, 20, 20, 20], // 增加边距
  html2canvas: {
    scale: 2,
    width: element.clientWidth, // 明确设置宽度
  },
  jsPDF: {
    unit: "mm",
    format: "a4",
    orientation: "portrait",
  },
};

7.5 长文档生成空白 PDF(Canvas 尺寸限制)

现象:html2pdf.js 超过一定长度的文档生成的 PDF 完全空白。

原因:HTML5 Canvas 有最大高度/宽度限制(Chrome 约 32,767 像素,Firefox 约 32,767 像素,IE 约 8,192 像素)。超出限制后 canvas 无法渲染。

各浏览器 Canvas 限制

浏览器最大高度/宽度最大面积
Chrome32,767 像素268,435,456 像素
Firefox32,767 像素472,907,776 像素
Internet Explorer8,192 像素N/A
iOS3-5 百万像素-

解决方案

  1. 降低 scale:将 scale 从 2 降至 1 或更低;
  2. 分页处理:将长文档拆分为多个部分分别生成;
  3. 限制内容高度:控制单次渲染的元素高度;
  4. 使用 jsPDF 原生 HTML 渲染器(实验性功能)。
// 降低 scale 以避免超出 canvas 限制
html2pdf()
  .set({
    html2canvas: { scale: 1 }, // 牺牲清晰度换取稳定性
  })
  .from(element)
  .save();

7.6 html2pdf.js 生成的PDF文字不可选中 / 搜索(固有局限)

现象:生成的 PDF 中文字无法选中、复制或搜索。

原因:html2pdf.js 将内容渲染为栅格图像后嵌入 PDF,而非矢量文本。

现状:这是 html2pdf.js 的架构性限制,目前无法避免。jsPDF 正在开发原生矢量渲染器,未来可能解决。

替代方案:如需可搜索文本,考虑使用 Puppeteer、Playwright 等基于 Chromium 的服务端方案。

7.7 Promise 冲突(与 Bluebird 等库冲突)

现象:页面使用了 Bluebird 等自定义 Promise 库时,html2pdf.js 报错或行为异常。

原因:html2pdf.js 依赖原生 Promise 的特定行为,与某些 polyfill 冲突。

解决方案

  1. 确保在 html2pdf.js 加载前不覆盖全局 Promise;
  2. 使用 thenExternal 退出 Worker 链后处理结果;
  3. 等待官方 Promise 沙箱化修复。

7.8 html2pdf.js 节点克隆导致 CSS 丢失 / 样式异常

现象:PDF 中的样式与页面显示不一致,特别是伪元素、CSS 变量等。

原因:html2pdf.js 克隆 DOM 的方式存在 bug,某些动态样式未被正确复制。

临时修复方案: 官方提供了 bugfix/clone-nodes-BUILD 分支的实验性修复:

# npm 安装修复版本
npm install eKoopmans/html2pdf.js#bugfix/clone-nodes-BUILD

或手动下载替换 dist/html2pdf.bundle.js

7.9 根元素被 resize 导致内容重排

现象:PDF 中内容布局与页面显示不同,出现意外的换行或缩放。

原因:html2pdf.js 默认将根元素 resize 以适应 PDF 页面宽度,导致内部内容重排(reflow)。

状态:这是设计行为,但某些场景下不期望。官方计划添加 shrink-to-page 等替代行为,但目前尚未实现。

缓解方案

  1. 为导出元素设置固定宽度;
  2. 使用 html2canvas.windowWidth 控制渲染视口宽度。

7.10 html2pdf.js XSS 安全漏洞(CVE-2026-22787)

影响版本:0.14.0 之前的所有版本。

漏洞描述:当传入文本字符串(而非 DOM 元素)作为源时,html2pdf.js 未对文本进行充分消毒,导致恶意脚本可被注入到 DOM 中执行。

攻击示例

const maliciousHTML = '<img src=x onerror="alert(document.cookie)">';
html2pdf(maliciousHTML); // 触发 XSS

修复方案

  1. 立即升级到 0.14.0 或更高版本(使用 DOMPurify 消毒文本源);
  2. 若无法升级,在传入 html2pdf.js 前自行消毒用户输入;
  3. 尽量使用 DOM 元素而非文本字符串作为源。
npm install [email protected] --save

八、html2pdf.js 与 html2canvas 的关系与协同

html2pdf.js 是 html2canvas 的上层封装,理解两者的关系有助于排查问题:

层面html2canvashtml2pdf.js
职责DOM → Canvas 图像渲染Canvas → PDF 封装 + 工作流程编排
输出<canvas> 元素.pdf 文件
配置html2canvas: { ... } 透传顶层配置 + 分页控制 + jsPDF 配置
限制CSS 支持不完整、跨域限制继承 html2canvas 所有限制 + 不可选中文本

调试技巧:若怀疑渲染问题来自 html2canvas,可单独测试:

// 单独测试 html2canvas
html2canvas(element).then((canvas) => {
  document.body.appendChild(canvas); // 查看 canvas 输出
});

若 canvas 本身有问题,则需调整 html2canvas 配置或修改 HTML/CSS;若 canvas 正常但 PDF 异常,则问题在 html2pdf.js 的 PDF 封装环节。

九、html2pdf.js 依赖与版本信息

依赖说明
html2canvasDOM 渲染引擎,负责将 HTML 转为 Canvas
jsPDFPDF 生成引擎,负责将图像封装为 PDF

使用打包版本 html2pdf.bundle.min.js 时,依赖已内置。使用非打包版本时,需按顺序引入:

<script src="jspdf.min.js"></script>
<script src="html2canvas.min.js"></script>
<script src="html2pdf.min.js"></script>

注意:html2pdf.js 无法在 Node.js 中运行,必须在浏览器环境中执行。

十、使用建议与注意事项

  1. 安全更新:务必使用 0.14.0 或更高版本,修复了 CVE-2026-22787 XSS 漏洞;
  2. 文本选择:如需可搜索/可选中的文本,html2pdf.js 不适合,考虑 Puppeteer 等服务端方案;
  3. 文件体积:由于栅格化输出,PDF 文件体积通常较大,可通过降低 qualityscale 优化;
  4. 长文档:注意 Canvas 尺寸限制,超过约 16,384 像素高度可能生成空白页;
  5. 字体加载:导出前确保自定义字体已完全加载,使用 document.fonts.ready 等待;
  6. Promise 库冲突:避免与 Bluebird 等自定义 Promise 库同时使用,或等待官方沙箱化修复。

也可以看看