vue2中使用jspdf插件实现页面自定义块pdf下载

发布于:2025-06-07 ⋅ 阅读:(21) ⋅ 点赞:(0)

实现pdf下载的环境

在这里插入图片描述
项目需求案例背景,点击【pdf下载】按钮,弹出pdf下载弹窗,显示需要下载四个模块的下载进度,下载完成后,关闭弹窗即可!

  • 项目使用的是Vue2,版本为^2.5.10;
  • jspdf插件版本为^2.5.1
  • html2canvas插件版本为^1.4.1

安装jspdf插件

npm install jspdf@2.5.1
npm install html2canvas@1.4.1

在项目中使用

下面是在项目中的使用相关的代码包括引入,状态,以及相关函数,模版的代码就直接省略掉了;仅供大家参考;

import JsPDF from "jspdf";
import html2Canvas from "html2canvas";
 data(){
   return {
     pdfDownLoadStatus:false,
     pdfDownLoadSteps:[],
   }
 }

点击事件以及相关函数

//点击pdf下载按钮事件
 downPdf(){
	 //pdf下载状态开启
	 this.pdfDownLoadStatus = true;
	 //需要截屏的区域,用在渲染pdf下载弹窗进度里面的内容
	 //code为页面下载区域的id
	 this.pdfDownLoadSteps = [
        { code: "idxxx1", name: "xx基本信息", status: "wait" },
        { code: "idxxx2", name: 'xx列表', status: "wait" },
        { code: "idxxx3", name: 'xx效果', status: "wait" },
        { code: "idxxx4", name: 'xx意见', status: "wait" },
      ];
      //打开pdf下载进度弹框,这里就这个弹窗模版中代码就省略掉了
      this.$refs.pdfDownloadModal.open();
      //pdf下载相关函数
      this.getPdf('下载文件名称');
 }async getPdf(title){
      let PDF = new JsPDF({
        unit: 'pt',
        format: 'a4',
        orientation: 'p',
      });
      let A4_WIDTH = 595.28
      let A4_HEIGHT = 841.89
      //pdf添加内容y轴起始位置
      let position = 0
      //判断是否有下载内容
      if (this.pdfDownLoadSteps && this.pdfDownLoadSteps.length > 0) {
        //y:pdf截屏区域的下标
        for (let y = 0 ; y < this.pdfDownLoadSteps.length ; y++) {
          //折叠面板
          let item = this.pdfDownLoadSteps[y];
          //开始
          item.status = 'valid';
          //将折叠面板转为canvas元素添加到pdf实例
          await this.toCanvasPanel(PDF, position, document.querySelector("#" + item.code), A4_WIDTH, A4_HEIGHT).then((data)=>{
            position = data.pdfPosition;
            this.generatePdf(item, this.pdfDownLoadSteps, y, title, PDF);
          });
        }
      }
 },

 /**
 * 生成PDF
  * @param item 当前区域下载状态
  * @param pdfDownLoadSteps 截屏的区域名
  * @param y 当前区域下标
  * @param title 文件标题
  * @param PDF
  */
  generatePdf(item, pdfDownLoadSteps, y, title, PDF) {
      //完成
      item.status = 'success';
      //最后一个截屏区域
      if (y == this.pdfDownLoadSteps.length - 1) {
        PDF.save(title + '.pdf');
        //pdf下载状态取消
        this.pdfDownLoadStatus = false;
      }
  },

 /**
 * 将折叠面板转为canvas元素添加到pdf实例
  * @param PDF
  * @param position 添加内容的起始位置
  * @param dom
  * @param imgWidth 图片宽度
  * @param pdfHeight pdf页高
  * @returns {Promise<unknown>}
  */
  toCanvasPanel(PDF, position, dom, imgWidth, pdfHeight){
      var p = new Promise(function(resolve, reject){
        html2Canvas(dom, {
          background: "#FFF"
        }).then(function (canvas) {
          //获取canavs转化后的宽度
          let contentWidth = canvas.width;
          //获取canavs转化后的高度
          let contentHeight = canvas.height;
          //高度转化为PDF的高度
          let imgHeight = imgWidth / contentWidth * contentHeight;
          //转化成图片Data
          let pageData = canvas.toDataURL('image/jpeg', 1.0);
          //PDF当前页剩余高度
          let pageResidue = pdfHeight - position;
          //添加图片到pdf
          PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
          //图片高度>PDF当前页剩余高度
          if (imgHeight > pageResidue) {
            //图片剩余高度=图片高度-当前页剩余高度
            let imgResidue = imgHeight - pageResidue;
            while (imgResidue > 0) {
              //下一页起始位置=图片剩余高度-图片高度
              position = imgResidue - imgHeight;
              //图片剩余高度-PDF高度,获取图片剩余高度
              imgResidue -= pdfHeight;
              //增加分页
              PDF.addPage();
              PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
            }
          }
          //下次截屏的起始位置
          position = position.add(imgHeight);
          resolve({'state': false, 'pdfPosition': position});
        })
      });
      return p;
  },