You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:54:58