前端使用html2canvas和JsPDF技术将html生成图片,并将图片导出为PDF文件(带页眉)

3,749 阅读2分钟

一、使用场景及优缺点

使用场景:前端生成单页的PDF文件,多页文件页面高度不易控制
优点:内容可变换性强,各种内容格式、样式大小可任意调节
缺点:
1.生成的PDF文件内容是图片,内容不可复制,生成的图片不清晰
2.生成多页文件时不灵活,需要在html代码中设置每页的高度

二、生成单页PDF文件方法示例

1.下载文件

npm install html2canvas jspdf --save

2.引入文件
import html2canvas from "html2canvas";
import JsPDF from "jspdf";
3.HTML
//要下载的PDF内的内容
<div class="content" ref="orderForm1" id="orderForm1">
PDF文件内容
</div>

//iview的Button组件
<Button class="download" type="primary" :loading="loading1" @click="download()" >
//按钮点击前后的状态切换
  <span v-if="!loading1">下载当前报告</span>
  <span v-else>下载中...</span>
</Button>
4.JS
download(){
    let _this = this
    let myBox = this.$refs.orderForm1; //获取ref里面的内容
    html2canvas(myBox, {
      useCORS: true, //是否尝试使用CORS从服务器加载图像  解决跨域
      allowTaint: true, // 解决跨域
      dpi: 300, //解决生产图片模糊
      scale: 6, //清晰度--放大倍数
    }).then(function (canvas) {
    //将html代码转换为图片
      let pageData = canvas.toDataURL('image/jpeg', 1.0)
      let PDF = new JsPDF('', 'pt', 'a4')
    //图片以左边距为35,上边距为65,宽为520,高为672的大小添加到PDF中生成PDF文件
      PDF.addImage(pageData, 'JPEG', 35, 65, 520, 672)
      PDF.save(_this.basic.entName + '.pdf')//下载PDF文件名称
    });

},
5.生成示例

页面: 1676604624217.jpg 生成的PDF文档:

1676604678876.jpg

1676604785836.jpg

三、生成多页PDF文件并添加文件页眉的方法

1.HTML
//要下载的PDF内的内容
<div class="content" ref="orderForm1" id="orderForm2">
PDF文件内容
</div>

//iview的Button组件
<Button class="download" type="primary" :loading="loading1" @click="download()" >
//按钮点击前后的状态切换
  <span v-if="!loading1">下载当前报告</span>
  <span v-else>下载中...</span>
</Button>
2.JS
download(){
  let _this = this
  let myBoxs = this.$refs.orderForm2; //获取ref里面的内容
  html2canvas(myBoxs, {
    useCORS: true, //是否尝试使用CORS从服务器加载图像  解决跨域
    allowTaint: true, // 解决跨域
    dpi: 300, //解决生产图片模糊
    scale: 2, //清晰度--放大倍数
  }).then(function (canvas) {
    let contentWidth = canvas.width
    let contentHeight = canvas.height
    let pageHeight = contentWidth / 592.28 * 841.89 // 一页pdf显示html页面生成的canvas高度;
    let canvasHeight = contentHeight - 2000 //未生成pdf的html页面高度
    let position = 0 //pdf页面偏移
    //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高  280*396
    let imgWidth = 420.28  //宽度  560.28
    let imgHeight = 420.28 / contentWidth * contentHeight   //592.28
    let pageData = canvas.toDataURL('image/jpeg', 1.0)
    let PDF = new JsPDF('', 'pt', 'a4')

    // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
    // 页面超过一页的高度
    if(canvasHeight > pageHeight) {
      // 第一页生成不带页眉的封页
      PDF.addImage(pageData, 'JPEG', 0, 60, 600, imgHeight)
      canvasHeight -= pageHeight
      position -= 740.89
      PDF.addPage()
      let canvasHeight
      // 之后每次生成带页眉的封页
      while (canvasHeight > 0) {
        let logo = document.getElementById("head"); //放在页眉的图标
        PDF.addImage(pageData, 'JPEG', 85, position, imgWidth, imgHeight)
        canvasHeight -= pageHeight
        position -= 860.89
        if (canvasHeight > -2000) {
          PDF.addImage(logo, 'PNG', 85,50,420, 24)
          PDF.addPage()
        }
      }
      let targetPage = PDF.internal.getNumberOfPages(); //获取总页
      PDF.deletePage(targetPage); // 删除目标页
    }

    PDF.save(_this.entInfoBasic.entName + '.pdf')//下载PDF文件名称
  }).catch(err=>{
    this.$Message.error(err.message)
  });

},

四、常见问题

1.生成的PDF文件非常不清晰
尝试修改配置中的scale属性,scale值越大,清晰度越高;但清晰度过高会导致图片生成不全,更可能PDF下载不下来。
2.PDF文件下载不下来,或者浏览器窗口铺满屏幕下载不了,而缩小屏幕可以下载下来
降低scale的值,清晰度降低,文件可正常生成。

总结:这种方法虽然可以实现前端生成PDF文件,但使用起来超级不灵活,不推荐大家使用此种方法生成页数多的PDF文件,生成一两页是可以使用的哦,欢迎大家补充提问!