html2Canvas+JsPDF,导出pdf

安装依赖

npm install html2canvas--save
npm install jspdf --save

 html2canvas 通过获取HTML的dom元素,然后生成Canvas,保存为图片      
 jsPDF  生成 PDF 文档

创建utils/htmlToPdf.js

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
  install(Vue, options) {
    /**
     *
     * @param {*} reportName 下载时候的标题
     * @param {*} isDownload  是否下载默认为下载,传false不下载
     */
    Vue.prototype.getPdf = function (reportName, isDownload = true) {
      return new Promise((resolve, reject) => {
        // 特别重要:当页面超过一页,出现滚动条,滚动的部分生成的图片为空白
        window.pageYoffset = 0
        document.documentElement.scrollTop = 0
        document.body.scrollTop = 0

        var title = reportName;
        html2Canvas(document.querySelector('#pdfDom'), {
          allowTaint: true,
          background: '#FFF',
        }).then((canvas) => {
          let contentWidth = canvas.width
          let contentHeight = canvas.height
          //一页pdf显示html页面生成的canvas高度;
          let pageHeight = contentWidth / 592.28 * 841.89
          //未生成pdf的html页面高度
          let leftHeight = contentHeight
          //页面偏移
          let position = 0
          //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
          let imgWidth = 592.28
          let imgHeight = 592.28 / contentWidth * contentHeight
          let pageData = canvas.toDataURL('image/jpeg', 1.0)
          let PDF = new JsPDF('', 'pt', 'a4')
          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
          //当内容未超过pdf一页显示的范围,无需分页
          if (leftHeight < pageHeight) {
            PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
          } else {
            while (leftHeight > 0) {
              PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
              leftHeight -= pageHeight
              position -= 841.89
              //避免添加空白页
              if (leftHeight > 0) {
                PDF.addPage()
              }
            }
          }
          if (isDownload) {
            PDF.save(title + '.pdf')
          }
          // 删除本地存储的base64字段
          var pdfData = PDF.output('datauristring') 
          resolve(pdfData)
        }
        )
      })
    }
  }
}

main.js引入

import htmlToPdf from "./utils/htmlToPdf.js"
Vue.use(htmlToPdf)

组件使用 

<div id="pdfDom">
    <div class="pdf-dom">
        // ... 分割dom
    </div>
    <div class="pdf-dom">
        // ... 分割dom
    </div>
    <div class="pdf-dom">
        // ... 分割dom
    </div>    
</div>


<van-button type="primary" @click="toGetPdf('pdf名称', false)">PDF</van-button>



// 直接导出download = true即可
toGetPdf(tile = "", download = false) {
  Toast.loading('请稍候...')
  let vm = this;
  vm.pdfPrint = true // 打印的pdf样式加载
  const A4_WIDTH = 592.28;
  const A4_HEIGHT = 841.89;
  vm.$nextTick(() => {
    // dom的id
    let target = document.getElementById('pdfDom');
    let pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT;
    // 获取分割dom,此处为class类名,避免分页处图片文字被截断
    let lableListID = document.getElementsByClassName('pdf-dom');
    // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割
    for (let i = 0; i < lableListID.length; i++) {
        let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight);
        if (vm.isSplit(lableListID, i, multiple * pageHeight)) {
            let divParent = lableListID[i].parentNode; // 获取该div的父节点
            let newNode = document.createElement('div');
            newNode.className = 'emptyDiv';
            newNode.style.background = '#ffffff';
            let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight);
            newNode.style.height = _H + 80 + 'px';
            newNode.style.width = '100%';
            let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点
            // 判断兄弟节点是否存在
            // console.log(123,next);
            if (next) {
                // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
                divParent.insertBefore(newNode, next);
            } else {
                // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
                divParent.appendChild(newNode);
            }
        }
    }

    this.pdfBtn = true
    vm.getPdf(tile, download).then((res) => {
        // 获取base64Pdf
        this.UploadPdf(res);
    });

  })
},

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值