使用jsPDF和canvas2html导出pdf踩坑记录

3,308 阅读2分钟

目前网上的教程基本都是采用canvas2html先转成图片,然后在使用jsPDF进行图片导出,这种方式导出的只是一直canvas绘制的图片,其中里面的文本内容和图片不能进行交互复制出来

因此我使用的方式是直接使用jsPDF的html()方法直接导出pdf,这样导出的pdf就能正常交互了

使用的jsPDF版本为2.3.1版本,html2canvas为1.0.0-rc.7

由于jsPDF对于中文等字形需要自己插入对应字体转换文件,转换地址为fontconverter

image.png

对应中文字形可以根据自己项目使用的字形进行转换,目前本人使用的是思源黑体的ttf文件,注意不要使用用otf文件,字体文件下载地址

这里可能存在字体文件太大,项目直接引入出现爆栈的问题,这里推荐使用script标签进行引入

// 字体样式使用
* {
    font-family: SourceHanSans;
}
// 资源引入
<script src="static/Pdf/html2canvas.min.js"></script>
<script src="static/Pdf/jspdf.umd.min.js"></script>
<script src="static/Pdf/SourceHanSans-normal.min.js"></script>

导出pdf方法

export default {
  install(Vue, options) {
    Vue.prototype.exportPdfFile = function (pdfName) {
      const JsPDF = window.jspdf.jsPdf
      let PDF = new JsPDF('p', 'pt', 'a4')
      let pdfDom = document.getElementById('#pdf')
      // 设置内容的宽高
      const targetWidth = pdfDom.clientWidth
      const targetHeight = pdfDom.clientHeight
      // a4纸的正常尺寸是宽592.28,高是841.89
      const pageWidth = 592.28
      const pageHeight = 841.89
      let contentHeight = pageWidth / targetWidth * targetHeight
      while (contentHeight > 0) {
        contentHeight -= pageHeight
        // 根据高度计算需要几个分页
        if (contentHeight > 0) {
          PDF.addPage()
        }
      }
      // 调用save方法生成pdf文件
      PDF.html(pdfDom, {
        callback: function (doc) {
          // 导出pdf
          doc.save(pdfName || '导出pdf.pdf')
        },
        x: 0,
        y: 0
      })
    }
  }
}

此时基本上能够成功导出pdf了,不过还存在一个问题:

jsPDF自定义了一套模拟canvas的对象进行pdf导出,而html2canvas是针对原生canvas进行pdf导出,因此使用jsPDF进行pdf导出时,对于css中的background图片不支持,会使用默认黑色背景填充。对于图片需要使用img标签进行图片插入才能正常导出