导出pdf

该方法导出的pdf大小是A4纸的尺寸,如果大于1页需要根据元素高度进行截断的话,页面元素需要加 class ergodic-dom,方法里面会获取ergodic-dom元素,对元素高度和A4高度做比较,如果大于A4高度,会塞一个空白元素,确保每一个元素在换页的时候不会被分割。

js 复制代码
import exportPDFMixin from '@/mixins/exportPDFMixin';
mixins: [exportPDFMixin],
html 复制代码
 <span v-show="showEdit" class="export textR" @click="exportPDF('pdfDom', '导出的pdf名称')">导出</span>
js 复制代码
//exportPDFMixin.js
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
export default {
  data() {
    return {
      showEdit: true
    }
  },
  methods: {
    exportPDF(elId, title = "pdf") {
      this.showEdit = false;
      this.$nextTick(() => {
        this.downloadPDF(elId, title);
      })
    },
    downloadPDF(elId, title) {
      html2Canvas(document.querySelector(`#${elId}`), {
        allowTaint: true,
        useCORS: true,
        onclone: (documentclone) => {
          this.formatNode(documentclone);
        }
      }).then((canvas) => {
        let contentWidth = canvas.width
        let contentHeight = canvas.height
        let pageHeight = contentWidth / 592.28 * 841.89
        let leftHeight = contentHeight
        let position = 0
        let imgWidth = 595.28
        let imgHeight = 592.28 / contentWidth * contentHeight
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
        let PDF = new JsPDF('', 'pt', 'a4')
        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()
            }
          }
        }
        PDF.save(title + '.pdf');
        this.showEdit = true;
      })
    },
    formatNode(documentclone) {
      let pageHeight = documentclone.querySelector("#pdfDom").scrollWidth / 592.28 * 841.89;
      let lableListID = documentclone.getElementsByClassName('ergodic-dom');
      for (let i = 0; i < lableListID.length; i++) {
        let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight)
        if (this.isSplit(lableListID, i, multiple * pageHeight)) {
          let divParent = lableListID[i].parentNode // 获取该div的父节点
          let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight)
          let newNode = this.getFooterElement(_H)
          let next = lableListID[i].nextSibling // 获取div的下一个兄弟节点
          // 判断兄弟节点是否存在
          if (next) {
            // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
            divParent.insertBefore(newNode, next)
          } else {
            // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
            divParent.appendChild(newNode)
          }
        }
      }
    },
    getFooterElement (remainingHeight, fillingHeight = 85) {
      let newNode = document.createElement('div')
      newNode.style.background = '#fff'
      newNode.style.width = 'calc(100% + 8px)'
      newNode.style.marginLeft = '-4px'
      newNode.style.marginBottom = '0px'
      newNode.style.height = (remainingHeight + fillingHeight) + 'px' // pdf截断需要一个空白位置
      return newNode
    },
    isSplit (nodes, index, pageHeight) {
      return nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight
    },
  }
}
相关推荐
Spider_Man41 分钟前
打造属于你的前端沙盒 🎉
前端·typescript·github
用户479492835691543 分钟前
🤫 你不知道的 JavaScript:`"👦🏻".length` 竟然不是 1?
前端·javascript·面试
掘金一周44 分钟前
凌晨零点,一个TODO,差点把我们整个部门抬走 | 掘金一周 9.11
前端·人工智能·后端
用户8174413427481 小时前
kubernetes核心概念 Service
前端
xingkongv1 小时前
从“调接口仔”到“业务合伙人”:前端的 DDD 初体验
javascript·前端框架
东北南西1 小时前
Web Worker 从原理到实战 —— 把耗时工作搬到后台线程,避免页面卡顿
前端·javascript
Zz_waiting.1 小时前
案例开发 - 日程管理 - 第六期
前端·javascript·vue.js·路由·router
A 风1 小时前
封装日期选择器组件,带有上周,下周按钮
开发语言·javascript·vue.js
袁煦丞1 小时前
企业微信开发者的‘跨网穿梭门’:cpolar内网穿透实验室第499个成功挑战
前端·程序员·远程工作
Simon_He1 小时前
vue-markdown-renderer:比 vercel streamdown 更低 CPU、更多节点支持、真正的流式渲染体验
前端·vue.js·markdown