将Vue页面导出为pdf格式并进行下载

1.使用npm下载两个插件

a.将html页面转换成图片
npm install --save html2canvas 
b.将图片生成pdf
npm install jspdf --save

2.在utils文件夹中创建一个名字叫个htmlToPdf.js的文件,内容如下:

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
  install(Vue, options) {
    Vue.prototype.getPdf = function (title) {
      var title = title
      var c = document.createElement("canvas")
      var opts = {
        scale: 1,
        canvas: c,
        logging: true,
        width: document.querySelector('#pdfDom').offsetWidth,
        height: document.querySelector('#pdfDom').offsetHeight
      };
      c.width = document.querySelector('#pdfDom').offsetWidth * 2
      c.height = document.querySelector('#pdfDom').offsetHeight * 2
      c.getContext("2d").scale(2, 2);
      html2Canvas(document.querySelector('#pdfDom'), opts).then(function (canvas) {
        // let getPixelRatio = function (context) {
        //   let backingStore = context.backingStorePixelRatio ||
        //     context.webkitBackingStorePixelRatio ||
        //     context.mozBackingStorePixelRatio ||
        //     context.msBackingStorePixelRatio ||
        //     context.oBackingStorePixelRatio ||
        //     context.backingStorePixelRatio || 1;
        //   return (window.devicePixelRatio || 1) / backingStore;
        // };

        let pdf = new JsPDF('', 'pt', 'a4')
        let ctx = canvas.getContext('2d')
        // var ratio = getPixelRatio(ctx);
        // console.log(ratio);
        // canvas.width = canvas.width * ratio;
        // canvas.width = canvas.height * ratio;
        // ctx.scale(2, 2);
        let a4w = 495 //A4大小,210mm x 297mm,像素是 595*842 的边距,左右各50px 上下各60px,显示区域495*722
        let a4h = 722
        let imgHeight = Math.floor(a4h * canvas.width / a4w)   //按A4显示比例换算一页图像的像素高度
        let splitPage = function ($dom) {
          const pageOffsetTop = $dom.offsetTop
          const pageOffsetWidth = $dom.offsetWidth
          const pageOffsetHeight = $dom.offsetHeight
          const $unitElements = $dom.querySelectorAll('.el-row')
          const peerPageHeight = pageOffsetWidth / a4w * a4h // 获取缩放后的一页页面高度
          const pages = [
            [
              {
                top: 0, // 起点初始化
                offsetTop: 0
              }
            ]
          ]
          // 遍历最小单元格
          // 获取单元格底部距离顶部的高度 top,以及 offsetTop
          // 根据 top 值,算出该单元格的页码,放入数组 pages
          $unitElements.forEach($element => {
            const offsetTop = $element.offsetTop - pageOffsetTop
            const top = offsetTop + $element.offsetHeight
            const pageIndex = parseInt(top / peerPageHeight)
            // 新的一页
            if (typeof pages[pageIndex] === 'undefined') {
              pages[pageIndex] = []
            }
            pages[pageIndex].push({
              top,
              offsetTop
            })
          })
          console.log(pages)
          return pages
        }
        let pages = splitPage(document.querySelector('#pdfDom'))
        pages.forEach((page, index) => {
          const { offsetTop } = page[0]
          const { top } = page[page.length - 1]
          let imgHeight1 = (top - offsetTop) * 2
          let pageA = document.createElement("canvas");
          pageA.width = canvas.width;
          // pdf.addImage(pageData, 'JPEG', 50, 60, a4w, top)
          pageA.height = Math.min(imgHeight1, canvas.height - offsetTop * 2);//可能内容不足一页
          if (index > 0) {
            pdf.addPage()
          }
            //用getImageData剪裁指定区域,并画到前面创建的canvas对象中
          pageA.getContext('2d').putImageData(ctx.getImageData(0, offsetTop * 2, canvas.width, Math.min(imgHeight1, canvas.height - offsetTop * 2)), 0, 0);
          pdf.addImage(pageA.toDataURL('image/jpeg', 1.0), 'JPEG', 50, 60, a4w, Math.min(a4h, a4w * pageA.height / pageA.width));    //添加图像到页面,保留左右各50px 上下各60px边距
        })

        pdf.save(title + '.pdf')

      })
    }
  }
}

3. 在main.js中注册我们自定义的插件htmlToPdf.js

import htmlToPdf from '@/components/utils/htmlToPdf'
Vue.use(htmlToPdf)

4.在按钮上直接绑定getPdf方法,即可实现导出功能

//这里面的内容是我们要导出的部分 id为"pdfDom",和上面"htmlToPdf.js"文件中的id必须一致.此部分将就是pdf显示的部分

 


//getPdf()是我们在main.js中绑定在Vue中的,固定名称,直接调用即可下载,无需在methods中写方法

 

export default {  //
  data () {
      return {
      htmlTitle: '页面导出PDF文件名'  //这个也是固定写法,pdf文件下载的名称
      }
  }
 }


参考:候鸟与暖风的将Vue页面导出为pdf格式并进行下载

你可能感兴趣的:(vue,vue)