导出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
    },
  }
}
相关推荐
2501_938799421 天前
CSS Container Queries:基于父容器的响应式设计
前端·css
一枚前端小能手1 天前
🔁 JavaScript中的迭代全攻略 - for/while/迭代器/生成器/for await...of详解
前端·javascript
用户11481867894841 天前
深入 V8 引擎与浏览器原理:从理论到 Vue 实战的完整指南
前端
spmcor1 天前
Vue命名冲突:当data和computed相爱相杀...
前端·面试
拉不动的猪1 天前
单点登录中权限同步的解决方案及验证策略
前端·javascript·面试
znhy@1231 天前
十三、JS进阶(二)
开发语言·前端·javascript
JarvanMo1 天前
Flutter:使用图像作为屏幕背景
前端
Mintopia1 天前
💰 金融Web应用中的AIGC风险控制技术与合规适配
前端·javascript·aigc
Mintopia1 天前
🚀 Next.js 压力测试与性能调优实战
前端·javascript·全栈
江城开朗的豌豆1 天前
TypeScript 类型系统漫游指南:从入门到爱上类型安全
前端·javascript