vue2 将页面生成pdf下载

项目场景:

在项目开发的过程中,经常有下载一些报表,有部分要求文档是pdf格式的文件,这时候可以插件快速地搭建一个将页面生成pdf文件的功能。


依赖支持

本次项目中主要使用的nodejs: 14.20.0,npm版本是6.14.17。

javascript 复制代码
npm install --save jspdf
npm install --save html2canvas;
npm install vue-router@3

实施步骤:

1、创建vue2项目

2、配置路由 router

3、搭建下载功能

创建utils文件夹,文件夹内创建htmlToPdf.js文件,并将其加载在main.js

javascript 复制代码
import htmlToPdf from '@/utils/htmlToPdf'

Vue.use(htmlToPdf)
javascript 复制代码
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
    
  install(Vue) {
    /**
     * 
     * @param {*} reportName 下载时候的标题
     * @param {*} isDownload  是否下载默认为下载,传false不下载
     */
    Vue.prototype.getPdf = function (reportName, isDownload = true) {
      //     var target = document.getElementsByClassName("right-aside")[0];
      // target.style.background = "#FFFFFF";
      return new Promise((resolve, reject) => {
        var title = reportName;
        html2Canvas(document.querySelector('#app'), {
          allowTaint: true
        }).then((canvas) => {
          let contentWidth = canvas.width
          let contentHeight = canvas.height
          //一页pdf显示html页面生成的canvas高度;
          let pageHeight = contentWidth / 592.28 * 841.89
          //未生成pdf的html页面高度
          let leftHeight = contentHeight
          //页面偏移
          let position = 0
          //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
          let imgWidth = 595.28
          let imgHeight = 592.28 / contentWidth * contentHeight
          let pageData = canvas.toDataURL('image/jpeg', 1.0)
          let PDF = new JsPDF('', 'pt', 'a4')
          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
          //当内容未超过pdf一页显示的范围,无需分页
          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()
              }
            }
          }
          if (isDownload) {
            PDF.save(title + '.pdf')
          }
          // 删除本地存储的base64字段
          var pdfData = PDF.output('datauristring')//获取base64Pdf
          resolve(pdfData)
        } 
        ).catch(error=>{
            reject(error)
        })
      })
    }
  }
}

4、开发功能,其中代码如下。初步的使用,已经可以下载pdf,具体的使用,需要根据自身的需求进行调整。

javascript 复制代码
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a @click="initData()" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <button @click="toGetPdf()">下载PDF</button>//这种情况是只下载,不上传后端
    <!-- <button @click="toGetPdf(1, 0)">下载PDF</button>//这种情况是只走上传后端接口,不下载 -->

    
  </div>
</template>

<script>
import { jsPDF } from "jspdf";

// Default export is a4 paper, portrait, using millimeters for units

export default {
  name: 'HelloWorld',
  data(){
    return {
      actName:'1111'
    }
  },
  methods:{
    initData(){
      const doc = new jsPDF();

      doc.text("Hello world!", 10, 10);
      doc.save("a4.pdf");
    },
    toGetPdf( ) {
      /**
     * val 决定走不走上传接口,默认为不上传给后端
     * download 默认是下载
     * /
 
      /* */
      this.$nextTick(() => {
        setTimeout(() => {
          window.scrollTo(0, 0);     //这行代码很重要,它让页面的滚动条跳到了最上方如果点击打印按钮的时候,滚动条没有在最上方,打印内容会是不完整的,体验也会差
          let title ="pdf文件"
          this.getPdf(title, true) //download:false为不下载,这里调用了刚刚引用的全局函数,.then得到的值是base64位的pdf文件
           
        }, 1000);
      });
    },
  },
  
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

项目总结:

方法并不是很难,稍微了解,说不定以后得项目中,会使用到。

从项目中学习,然后自己重构,有助于自身快速的成长。

相关推荐
AI大模型-小华39 分钟前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子3 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅3 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni3 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学5 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端
赵庆明老师5 小时前
Vben精讲:21-详解web-antd:tsconfig.json
前端·json·vim
wc885 小时前
微软EDGE浏览器功能学习
前端·学习·edge
Csvn6 小时前
🎯 原生 `<dialog>` 元素:终于可以扔掉一半的自定义弹窗组件了?
前端
Csvn6 小时前
🎨 CSS @layer:用「层叠优先级」终结样式打架的世纪难题
前端