jspdf 初始化生成空白页因默认创建空文档,需手动添加内容;转dom需html2canvas配合并设scale/usecors;中文需注册支持utf-8的字体;save()须在用户手势事件内调用以防拦截。

jsPDF 初始化时为什么生成的 PDF 是空白页
常见现象是调用 new jsPDF() 后直接 save(),结果下载一个只有白纸、没内容的 PDF。这是因为 jsPDF 默认创建的是空文档,不自动渲染 DOM 或文本——你得手动添加内容。
最简可行路径是先加一段文字:
const doc = new jsPDF();
doc.text("Hello World", 10, 10);
doc.save("hello.pdf");注意坐标单位是毫米,默认原点在左上角,text() 的第二、三个参数是 x、y 位置,太小(如 y=5)可能被裁剪,建议 y ≥ 10。把网页某块区域(比如 div)转成 PDF 却模糊或错位
直接用 html() 方法(jsPDF + html2canvas 组合)是最常用方式,但容易出问题:html2canvas 截图默认忽略 CSS transform、fixed 定位、跨域图片,且缩放比例不设好会糊。
关键配置项必须显式传入:
-
scale: 2—— 提升截图分辨率,避免文字发虚 -
useCORS: true—— 加载同域/已配 CORS 的图片 -
logging: false—— 关闭控制台冗余日志 - 确保目标
div有明确宽高,无overflow: hidden截断内容
html2canvas(document.getElementById("content")).then(canvas => {
const imgData = canvas.toDataURL("image/png");
const doc = new jsPDF("p", "mm", "a4");
const imgWidth = 210; // A4 宽度 mm
const imgHeight = (canvas.height * imgWidth) / canvas.width;
doc.addImage(imgData, "PNG", 0, 0, imgWidth, imgHeight);
doc.save("content.pdf");
});
中文显示为方块或乱码
jsPDF 原生不支持 UTF-8 中文,text() 直接写中文会变成方框。必须注册自定义字体(.ttf 文件),且该字体需包含中文字形。
操作分三步:
- 用
jsPDF.setFont()前,先用doc.addFont()加载字体(推荐思源黑体、Noto Sans SC 等开源可商用字体) - 调用
doc.setFont("yourFontName", "normal")切换字体族 - 确保字体文件通过
fetch()或import正确加载,路径不能 404;否则静默失败,仍显示方块
const doc = new jsPDF();
const fontUrl = "/fonts/NotoSansSC-Regular.ttf";
fetch(fontUrl).then(res => res.arrayBuffer()).then(buf => {
doc.addFont(buf, "NotoSansSC", "normal");
doc.setFont("NotoSansSC");
doc.text("你好世界", 20, 20); // 这行才真正生效
});
调用 save() 没反应或被浏览器拦截
现代浏览器对非用户手势触发的 save()(比如异步回调里、setTimeout 里)会静默拦截下载,表现为无任何提示、无文件弹出。
唯一可靠解法:所有 PDF 生成和保存逻辑,必须包裹在用户显式交互事件内,例如:
- 按钮
onclick回调 -
addEventListener("click", ...)绑定的函数 - 不能放在
Promise.then()、setTimeout、fetch().then()等异步链深处
save() 放在最终的 .then 里,并确保初始 click 事件没被 preventDefault 或 stopPropagation 干扰。另外注意:Safari 对 data URL 下载支持差,doc.output("dataurlnewwindow") 可能打不开,优先用 doc.save("xxx.pdf")。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











