jsPDF+html2Canvas生成PDF无法在Acrobat Reader打开问题
问题描述
使用jsPDF结合html2Canvas生成的PDF文件可在所有浏览器正常打开,但无法在Adobe Acrobat Reader中打开,报错提示:此页面存在错误,Acrobat可能无法正确显示页面,请联系创建PDF文档的人员解决问题。该PDF可在Chrome中打开。
相关代码
downloadPDFGraphs() { if (this.onPDFDownload) { this.$emit("onPDFDownload"); return; } this.download("pdf"); }, download(type) { const todayDate = moment().format("DD MMM YYYY hh:mm:ss").toUpperCase(); let container = document.querySelector("#" + this.downloadId); let filename = this.titleChart + "_" + todayDate + "." + type; if (this.specificSiteId && this.specificSiteId.length > 0) { filename = this.titleChart + "_" + todayDate + "_" + getSiteID(this.specificSiteId[0]) + "." + type; } html2canvas(container, { allowTaint: true, logging: false, height: !this.zoomGraphValueChild ? 400 : 550, scrollY: -window.scrollY, useCORS: true, scrollX: -window.scrollX, onclone: (document) => { if (this.specificSiteId && this.specificSiteId.length > 0) { if ( document.querySelector("#" + this.downloadId + " .title-date") != null ) { document .querySelector("#" + this.downloadId + " .title-date") .append("_" + this.getSiteID(this.specificSiteId[0])); } else { document .querySelector( "#" + this.downloadId + " .card-management-title" ) .append("_" + this.getSiteID(this.specificSiteId[0])); } } document .querySelectorAll("#" + this.downloadId + " .custom-tooltip") .forEach((element) => { element.remove(); }); document .querySelectorAll("#" + this.downloadId + " .apexcharts-toolbar") .forEach((element) => { element.remove(); }); document .querySelectorAll("#" + this.downloadId + " .remove-elem-download") .forEach((element) => { element.remove(); }); document .querySelectorAll("#" + this.downloadId + " .remove-zoom-icons") .forEach((element) => { element.remove(); }); document .querySelectorAll("#" + this.downloadId + " .nav-item") .forEach((element) => { const ele = element.querySelector(".nav-link.active"); if (!ele) { element.remove(); } }); if (this.downloadId === "studyMaps") { let dateTime = document.createElement("div"); dateTime.classList.add("ml-15"); dateTime.textContent = todayDate; document.querySelector("#" + this.downloadId).append(dateTime); } else { if (this.downloadId === "completion-data") { let dateTime = document.createElement("div"); dateTime.classList.add("ml-15"); dateTime.textContent = todayDate; document.querySelector("#" + this.downloadId).append(dateTime); if (document.querySelectorAll(".table-content").length > 0) { document.querySelectorAll(".table-content")[0].className = "remove-overflow"; } if (document.querySelectorAll(".rtl-display").length > 0) { document.querySelectorAll(".rtl-display")[0].className = "ltr-display"; } } else if(this.downloadId === "daily-sensor-compliance"){ let dateTime = document.createElement("div"); dateTime.classList.add("ml-15"); dateTime.textContent = todayDate; document.querySelector("#" + this.downloadId).append(dateTime); } else { document.querySelector("#" + this.downloadId).innerHTML += '<div class="ml-15">' + todayDate + "</div>"; } } }, }).then((canvas) => { if (type === "pdf") { const imgData = canvas.toDataURL("image/png"); let pdf = new jspdf("p", "mm", "a4"); const imgProps = pdf.getImageProperties(imgData); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; pdf.addImage(imgData, "PNG", 0, 0, pdfWidth - 5, pdfHeight); pdf.save(filename); } else if (type === "png") { let link = document.createElement("a"); document.body.appendChild(link); link.download = filename; link.href = canvas.toDataURL("image/png"); link.target = "_blank"; link.click(); } }); },
解决方案
针对Adobe Acrobat Reader无法打开生成的PDF问题,可尝试以下修复方案:
更换图片格式并添加压缩参数
将canvas导出格式从PNG改为JPEG,Acrobat对JPEG的兼容性更好,同时设置合理的压缩质量:// 替换原imgData生成代码 const imgData = canvas.toDataURL("image/jpeg", 0.95);修正PDF图片的边距与尺寸
原代码中pdfWidth - 5的宽度设置可能导致图片超出PDF页面边界,Acrobat对边界溢出的容错性更低,改为使用带安全边距的设置:// 替换addImage的参数,10为上下左右边距 pdf.addImage(imgData, "JPEG", 10, 10, pdfWidth - 20, pdfHeight);升级jsPDF到最新版本
旧版本jsPDF可能存在PDF规范兼容bug,升级到最新稳定版(如2.5.1及以上),避免库本身导致的PDF结构异常。统一使用DOM操作添加元素
在onclone回调的else分支中,innerHTML +=拼接HTML可能引入无效字符,改为用createElement方式添加日期元素:// 替换原else分支的innerHTML代码 let dateTime = document.createElement("div"); dateTime.classList.add("ml-15"); dateTime.textContent = todayDate; document.querySelector("#" + this.downloadId).append(dateTime);验证canvas生成的图片完整性
先将canvas导出的图片保存为本地文件,确认图片能在Acrobat中正常查看,排除html2canvas生成的图片本身损坏的可能。
内容的提问来源于stack exchange,提问作者Shailendra Tiwari
相关产品推荐
相关产品推荐

