vue导出横版pdf并解决内容分割问题

  • 准备工作和vue导出PDF一样,接下来讲的是一些区别

  • 首先是div中
    div中将要导出的div层添加ref,相关子内容标签加上 class=“item” 为了后续内容分割处理

<template>
  <div class="app-container" ref="report">
    <div style="position: absolute;top: 30px;right:25px;line-height: 70px;display: flex;justify-content: right;width: 90%;">
      <el-button type="text" @click="exportPDF">导出为pdfel-button>div>
    <div class="item">内容div>
    <div class="item">内容div>
    <div class="item">内容div>
    <div class="item">内容div>
 div>
<template>
  • methods中
    部分注释内容为竖版pdf
    isSplit (nodes, index, pageHeight) {
      // 计算当前这块dom是否跨越了a4大小,以此分割
      return !!(nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight);
    },
 // 导出为pdf
    exportPDF(){
      this.$message.warning('正在处理中,请稍后')
      // report ref
      let PDFView = this.$refs.report
      // 获取分割dom,此处为class类名为item的dom
      let lableListID = document.getElementsByClassName('item');
      let pageHeight = PDFView.scrollWidth / 841.89 * 595.28;//(横版pdf)
      // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空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 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 + 30 + 'px';
          newNode.style.width = '100%';
          let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点
          // 判断兄弟节点是否存在
          // console.log(next);
          if (next) {
            // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
            divParent.insertBefore(newNode, next);
          } else {
            // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
            divParent.appendChild(newNode);
          }
        }
      }

      html2Canvas(PDFView,{
        useCORS: true, //是否尝试使用CORS从服务器加载图像
        allowTaint: true,
        dpi: 300, //解决生产图片模糊
        scale: 3, //清晰度--放大倍数
      }).then(
        (canvas)=>{
        let contentWidth = canvas.width
        let contentHeight = canvas.height
        // let pageHeight = contentWidth / 592.28 * 841.89 // 一页pdf显示html页面生成的canvas高度;
        let pageHeight = contentWidth /  841.89 * 595.28 // 一页pdf显示html页面生成的canvas高度(横版pdf);
        let leftHeight = contentHeight //未生成pdf的html页面高度
        let position = 0 //pdf页面偏移

        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
        // let imgWidth = 595.28
        // let imgWidth = 560.28  //宽度
        // let imgHeight = 592.28 / contentWidth * contentHeight
        let imgWidth = 808  //宽度(横版pdf)
        let imgHeight = 841.89 / contentWidth * contentHeight//(横版pdf)
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
        let PDF = new JsPDF('l', 'pt', 'a4')
        if (leftHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
            leftHeight -= pageHeight
            position -= 595.28//(横版pdf)
            //position -= 841.89
            if (leftHeight > 0) {
              PDF.addPage()
            }
          }
        }
        PDF.save(this.prize.actName+'活动报告'+ '.pdf')//下载标题
        //将前面处理内容分割问题在页面中加上的空白占位结点去掉
        let emptyDiv = document.getElementsByClassName('emptyDiv');
        for(let i =0;i<emptyDiv.length;i++){
          emptyDiv[i].remove()
          i=i-1
         }
      })
    }

部分内容参考:HTML导出PDF以及解决内容被分割问题

关于内容分割不准确

原因:样式定位问题(offsetTop 计算的是距离父组件的距离,非最外层,部分样式定位及其他原因可能造成分割不准确。)
优化部分代码:

    isSplit(nodes, index, pageHeight) {
      // 计算当前这块dom是否跨越了a4大小,以此分割
      return !!(this.calc(nodes[index],-84) + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && this.calc(nodes[index+1],-84) + nodes[index + 1].offsetHeight > pageHeight);
    },
    // 计算元素距离顶部位置
    calc(dom, distance) {
      distance = distance || 0
      if (['BODY',null].includes(dom.offsetParent.nodeName)) {
        distance += dom.offsetTop
        return distance
      } else {
        distance += dom.offsetTop
        return this.calc(dom.offsetParent,distance)
      }
    },

你可能感兴趣的:(vue.js,pdf,javascript)