使用JSPDF和Html2Canvas导出PDF体积过大 如何缩小文件大小?
jsPDF + Html2Canvas 导出PDF体积过大优化方案
核心问题分析
你当前代码存在3个直接导致体积超大的问题:
- 导出的图片未做压缩,且使用无损PNG格式转存JPG,无压缩增益
- 每一页都重复插入完整的长图,相同图片资源被多次存储
- html2canvas默认使用高设备像素比生成画布,图片分辨率过高
可直接落地的优化方案
1. 调整图片压缩参数
将canvas导出格式改为JPG,同时设置合理的压缩质量(0.6-0.8区间肉眼几乎无差异,体积可降低60%以上)
2. 配置html2canvas降低输出分辨率
手动设置scale参数,不用跟随设备高DPI生成超高清画布,普通打印/屏幕查看设为1-1.5即可
3. 开启jsPDF压缩,复用图片资源
jsPDF初始化时开启压缩,插入图片时设置alias参数,同一张图片仅存储一次,多页复用不会重复占用空间
4. (可选)分块裁切生成单页图片
如果页数较多,可直接按PDF每页高度裁切canvas,每页仅插入对应区域的图片,避免单张长图体积过大
优化后代码示例
$('#print').click(function (e) { e.preventDefault(); let HTML_Width = $(".report").width(); let HTML_Height = $(".report").height(); let top_left_margin = 1; let PDF_Width = HTML_Width + (top_left_margin * 2); let PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2); let canvas_image_width = HTML_Width; let canvas_image_height = HTML_Height; let totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1; // 配置html2canvas降低分辨率,减少画布大小 html2canvas($(".report")[0], { scale: 1.5, // 原默认是window.devicePixelRatio,一般是2/3,改1.5清晰度足够体积减半 useCORS: true // 避免跨域图片导出失败 }).then(function (canvas) { // 导出为JPG格式,设置0.7的压缩质量 let imgData = canvas.toDataURL("image/jpeg", 0.7); // 初始化jsPDF时开启压缩 let pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height], {compress: true}); // 插入第一张图时设置alias,后续复用 pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, canvas_image_width, canvas_image_height, 'reportImg'); for (let i = 1; i <= totalPDFPages; i++) { pdf.addPage(PDF_Width, PDF_Height); // 复用之前的图片alias,不会重复存储图片数据 pdf.addImage('reportImg', 'JPG', top_left_margin, -(PDF_Height * i) + (top_left_margin * 4), canvas_image_width, canvas_image_height); } pdf.save("Report.pdf"); $(".html-content").hide(); }); });
进阶优化方案
如果上述优化后体积仍不符合要求,可替换导出逻辑:
- 文本占比高的场景,使用jsPDF内置的
html()方法直接导出DOM,文本会保留矢量格式,不会转成图片,体积可降低80%以上,清晰度也更高 - 移除导出内容中不必要的高清背景图、渐变效果,html2canvas渲染这类元素时会大幅增加画布体积
内容的提问来源于stack exchange,提问作者Osama Amr
相关产品推荐
相关产品推荐

