vue纯前端页面pdf导出下载

下载插件

npm install html2canvas --save
npm install jspdf --save

创建导出函数文件htmlToPdf.js

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
  install(Vue, options) {
    Vue.prototype.getPdf = function(fileName, divId) {
      var element = document.getElementById(divId)
      var title = fileName // PDF文件标题
      var c = document.createElement('canvas')// 创建照片
      var opts = {
        scale: 1,
        canvas: c,
        logging: true,
        pageX: 0,
        width: element.clientWidth,
        height: element.clientHeight
      }
      // 照片高度和宽度是页面元素的两倍
      c.width = element.clientWidth * 1
      c.height = element.clientHeight * 1
      c.getContext('2d').scale(1, 1)
      html2Canvas(element, opts)
        .then(function(canvas) {
          const contentWidth = canvas.width
          const contentHeight = canvas.height
          const pageHeight = contentWidth / 592.28 * 841.89
          let leftHeight = contentHeight
          let position = 0
          const imgWidth = 595.28
          const imgHeight = 592.28 / contentWidth * contentHeight
          const pageData = canvas.toDataURL('image/jpeg', 1.0)
          const PDF = new JsPDF('', 'pt', 'a4')
          if (leftHeight < pageHeight) {
            // 第一个20是img和pdf页面的左边距,第二个20是img与pdf页面的上边距
            PDF.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight)
          } else {
            while (leftHeight > 0) {
              PDF.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
              leftHeight -= pageHeight
              position -= 841.89
              if (leftHeight > 0) {
                PDF.addPage()
              }
            }
          }
          PDF.save(title + '.pdf')
        })
    }
  }
}

在 main.js 文件里引入并全局注册

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

在页面上使用

<template>
  <div class="div-container">
    <div>
      <el-button @click="pdf()">导出为PDF</el-button>
    </div>
    <!--    打印画布-->
    <div id="content" style="width: 600px">
      <div style="margin-top: 20px;height: 824px;width: 550px; border: black solid 1px">
        <!--        封面-->
        <div>
          <img src="/img/hnBackGroudTop.png" >
        </div>
        <div style="text-align: center">
          <h1 style="color: #6a3b50">个人健康风险评估报告</h1>
        </div>
        <div>
          <el-form ref="formData" :model="form" label-width="auto" class="form-container">
            <div>
              <div style="display: flex;width: 100%" class="form-container">
                <p style="font-size: 20px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</p><p class="underline">&nbsp;&nbsp;&nbsp;&nbsp;{{ form.name }}&nbsp;&nbsp;&nbsp;&nbsp;</p>
              </div>
              <div style="display: flex;width: 100%" class="form-container">
                <p style="font-size: 20px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</p><p class="underline">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ form.sex }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
              </div>
              <div style="display: flex;width: 100%" class="form-container">
                <p style="font-size: 20px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</p><p class="underline">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ form.age }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
              </div>
              <div style="display: flex;width: 100%" class="form-container">
                <p style="font-size: 20px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</p><p class="underline">&nbsp;&nbsp;{{ form.lorgName }}&nbsp;&nbsp;</p>
              </div>
              <div style="display: flex;width: 100%" class="form-container">
                <p style="font-size: 20px">评估日期:</p><p class="underline">&nbsp;&nbsp;{{ form.checkDate }}&nbsp;&nbsp;</p>
              </div>
            </div>
          </el-form>
        </div>
        <div style="margin-top: 95px">
          <img src="/img/hnBackGroudFoot.png" style="width: 100%">
        </div>
      </div>
      <div style="height: 824px;width: 550px ;margin-top: 20px; border: black solid 1px">
        <!--        目录-->
        <div style="display:flex;margin-top: 20px">
          <div style="width: 20%">
            <div class="line" />
            <div class="line2" />
          </div>
          <div><i class="el-icon-tickets" style="color: #78aa59;font-size: 28px" /><span style="font-size: 28px;color: #78aa59"> 目 录 </span></div>
          <div style="width: 61%">
            <div class="line1" />
            <div class="line3" />
          </div>
        </div>
        <div style="display: flex;margin-top: 10px" v-for="(item,index) in form.directory" :key="index">
          <div style="font-size: 20px;width: 90%">&nbsp;&nbsp;&nbsp;{{item.directoryName}}</div>
          <div class="line-container"></div>
          <div style="font-size: 20px;width: 10%">{{index}}</div>
        </div>
      </div>
      <div style="height: 824px;width: 550px ;margin-top: 20px; border: black solid 1px">
        <!--        个人信息汇总-->
        <div style="display:flex;margin-top: 20px">
          <div style="width: 20%">
            <div class="grLine1" />
            <div class="grLine2" />
          </div>
          <div><span style="font-size: 28px;color: #78aa59"> 个人信息汇总 </span></div>
          <div style="width: 49%">
            <div class="grLine3" />
            <div class="grLine4" />
          </div>
        </div>
        <div style="margin-top: 50px;display: flex;justify-content: center;align-items: center;">
          <table style="border: 1px solid black;border-collapse:collapse;" width="80%">
            <tr style="height: 34px">
               <td class="tableTdOne">
                 姓名
               </td>
               <td  class="tableTd">
                 马冬梅
               </td>
               <td  class="tableTdOne">
                 性别
               </td>
               <td  class="tableTd"></td>
               <td  class="tableTdOne">
                 年龄
               </td>
               <td  class="tableTd">
                 33
               </td>
             </tr>
            <tr style="height: 34px">
              <td class="tableTdOne">
                身高
              </td>
              <td  class="tableTd">
                163
              </td>
              <td  class="tableTdOne">
                体重
              </td>
              <td  class="tableTd">
                62
              </td>
              <td  class="tableTdOne">
                BIM
              </td>
              <td  class="tableTd">
                23.3
              </td>
            </tr>
            <tr style="height: 34px">
              <td class="tableTdOne">
                婚否
              </td>
              <td  class="tableTd">
                已婚
              </td>
              <td  class="tableTdOne">
                手机号
              </td>
              <td  class="tableTd">
                13589659579
              </td>
              <td  class="tableTdOne">

              </td>
              <td  class="tableTd">

              </td>
            </tr>
          </table>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
// import html2canvas from 'html2canvas'
// import jsPDF from 'jspdf'
import { getTime } from '@/utils'

export default {
  name: 'PdfPreview',
  components: {},
  data () {
    return {
      form: {
        name: '张三',
        sex: '女',
        age: '20',
        lorgName: '运营部门',
        checkDate: '2021-09-01',
        directory: [
          { directoryName: '个人健康信息汇总', numberOfPages: '01' },
          { directoryName: '主要生理指标', numberOfPages: '03' },
          { directoryName: '行为与生活方式评价', numberOfPages: '06' },
          { directoryName: '肥胖症风险评估报告', numberOfPages: '08' },
          { directoryName: '高血压风险评估报告', numberOfPages: '10' },
          { directoryName: '糖尿病风险评估报告', numberOfPages: '12' },
          { directoryName: '代谢综合征风险评估报告', numberOfPages: '14' },
          { directoryName: '缺血性心血管病风险评估报告', numberOfPages: '16' },
          { directoryName: '脑卒中风险评估报告', numberOfPages: '18' },
          { directoryName: '血脂异常危险评估报告', numberOfPages: '20' },
          { directoryName: '骨质疏松性骨折风险评估报告', numberOfPages: '22' },
          { directoryName: '抑郁症风险评估报告', numberOfPages: '24' },
          { directoryName: '睡眠呼吸暂停综合征风险评估报告', numberOfPages: '25' },
          { directoryName: '运动风险评估报告', numberOfPages: '27' },
          { directoryName: '肺癌风险评估报告', numberOfPages: '29' },
          { directoryName: '乳腺癌风险评估报告', numberOfPages: '31' },
          { directoryName: '推荐膳食方窝', numberOfPages: '33' },
          { directoryName: '推荐运动方案', numberOfPages: '35' }
        ]
      }
    }
  },
  computed: {},
  watch: {},
  mounted() {},
  methods: {
    pdf() {
      var fileName = this.form.name + '个人健康风险评估报告'
      this.getPdf(fileName, 'content')
    }

  }
}
</script>

<style lang="scss">
  .underline {
    font-size: 20px;
    text-decoration: underline;
  }
  .form-container {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .div-container{
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
  .centered-div {
    /* 样式设置 */
  }
  .line {
    margin-top: 5px;
    width: 100%;
    height: 6px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .grLine1 {
    margin-top: 5px;
    width: 100%;
    height: 9px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .line2 {
    margin-top: 5px;
    width: 100%;
    height: 3px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .grLine2 {
    margin-top: 5px;
    width: 100%;
    height: 2px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .line1 {
    margin-top: 5px;
    width: 100%;
    height: 6px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .grLine3 {
    margin-top: 5px;
    width: 100%;
    height: 9px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .line3 {
    margin-top: 5px;
    width: 100%;
    height: 3px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .grLine4 {
    margin-top: 5px;
    width: 100%;
    height: 2px;
    background: #78aa59;
    position: relative;
    text-align: center;
  }
  .line-container {
    border: 1px dashed #000; /* 设置边框为1像素宽、虚线样式和颜色 */
    margin-top: 16px;
    height: 0;
    width: 55%;
  }
  .tableTdOne {
    border: 1px solid black;
    background-color: #edf5e3;
  }
  .tableTd {
    border: 1px solid black;
  }

</style>

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