You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

调用jsPDF的addImage函数时遭遇"Incomplete or corrupt PNG file"错误的求助

解决jsPDF addImage报"Incomplete or corrupt PNG file"的问题

我之前也碰到过一模一样的报错,折腾了好一阵,给你几个亲测有效的排查方向:

1. 先处理隐藏元素的渲染问题

你的reportContentdisplay: none状态,html2canvas对完全隐藏的元素渲染经常会出问题,导致生成的canvas数据不完整。可以试试临时显示这个元素再渲染:

generatePDF(htmlContent) {
  // 先保存原有样式,临时显示元素
  const originalDisplay = htmlContent.style.display;
  htmlContent.style.display = 'block';

  html2canvas(htmlContent, {
    logging: false, // 关闭日志减少干扰
    useCORS: true // 内容里有跨域图片的话必须开启
  }).then(canvas => {
    // 渲染完成后恢复原隐藏状态
    htmlContent.style.display = originalDisplay;

    const imgWidth = 290;
    const imgHeight = (canvas.height * imgWidth / canvas.width);
    const contentDataURL = canvas.toDataURL('image/png', 1.0); // 指定质量为1.0避免压缩导致的损坏
    const pdf = new jsPDF('l', 'mm', 'a4');
    const position = 10;
    pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
    pdf.save('report.pdf');
  }).catch(err => {
    // 出错也要恢复样式,避免页面异常
    htmlContent.style.display = originalDisplay;
    console.error('渲染出错:', err);
  });
}

2. 改用canvas.toBlob替代toDataURL

有时候toDataURL生成的base64字符串会因长度或编码问题导致jsPDF解析失败,换成toBlob直接传入blob对象试试:

generatePDF(htmlContent) {
  const originalDisplay = htmlContent.style.display;
  htmlContent.style.display = 'block';

  html2canvas(htmlContent).then(canvas => {
    htmlContent.style.display = originalDisplay;

    canvas.toBlob((blob) => {
      const imgWidth = 290;
      const imgHeight = (canvas.height * imgWidth / canvas.width);
      const pdf = new jsPDF('l', 'mm', 'a4');
      const position = 10;
      // 直接传入blob对象,避免base64转码问题
      pdf.addImage(blob, 'PNG', 0, position, imgWidth, imgHeight);
      pdf.save('report.pdf');
    }, 'image/png');
  });
}

3. 锁定稳定的版本组合

虽然你说已经降级过,但还是要确认版本搭配:目前比较稳定的组合是html2canvas@1.4.1 + jsPDF@2.5.1,可以完全卸载现有包后重新安装:

npm uninstall jspdf html2canvas
npm install jspdf@2.5.1 html2canvas@1.4.1

4. 确保canvas完全渲染后再生成PDF

有时候html2canvas的then回调触发时,canvas内容可能还没完全渲染完毕,可以加个小延迟或者检查canvas状态:

html2canvas(htmlContent).then(canvas => {
  setTimeout(() => {
    // 这里执行生成PDF的逻辑
    const imgWidth = 290;
    const imgHeight = (canvas.height * imgWidth / canvas.width);
    const contentDataURL = canvas.toDataURL('image/png');
    const pdf = new jsPDF('l', 'mm', 'a4');
    const position = 10;
    pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
    pdf.save('report.pdf');
  }, 500);
});

另外还要注意:如果reportContent里包含跨域图片,一定要在html2canvas的配置中加上useCORS: true,否则生成的canvas会被污染,导出的图片数据必然损坏。

内容的提问来源于stack exchange,提问作者Mohamed Ibrahim

火山引擎 最新活动