vue2前端导出pdf文件

目录

1、安装依赖

?2、demo

[2.1 demo1导出效果](#2.1 demo1导出效果)

2.2?demo2导出效果

2.3?demo3导出效果

3、源码?

[3.1 demo1](#3.1 demo1)

[3.2 demo2](#3.2 demo2)

[3.3 demo2](#3.3 demo2)


1、安装依赖

导出PDF通常涉及将HTML内容转换为图片(截图),然后将这些图片插入到PDF文档中。这个过程可以通过使用**html2canvas? jspdf?**这两个库来实现:

npm install jspdf html2canvas **或 cnpm**install jspdf html2canvas

安装完成后,package.json文件生成如下:

2、demo

2.1 demo1导出效果

源码中 【导出PDF】导出时,不会分页导出。

2.2demo2导出效果

源码中 【导出PDF2】导出时,会分页导出。

2.3demo3导出效果

源码中 【导出PDF3】导出时,会分页导出。

3、源码

<template>
  <div>
    <div style="margin-top: 50px;text-align: center"  >
      <el-button type="primary" @click="exportPDF">导出PDF</el-button>
      <el-button type="primary" @click="exportPDF2">导出PDF2</el-button>
      <el-button type="primary" @click="getPdf()" >导出PDF3</el-button>
    </div>
    <div style="margin-left: 200px;margin-top: 10px;margin-right: 150px" ref="pdfContent" id="pdfDom"  class="mmm" >
      <el-table :data="tableData" style="width: 100%">
        <el-table-column prop="date" label="日期" width="180"></el-table-column>
        <el-table-column prop="name" label="姓名" width="180"></el-table-column>
        <el-table-column prop="address" label="地址"></el-table-column>
      </el-table>
      <h1>1Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>2Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>3Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
      <h1>4Element 默认提供一套主题,CSS 命名采用 BEM 的风格,方便使用者覆盖样式。</h1>
    </div>
  </div>
</template>

<script>
  import jsPDF from 'jspdf';
  import html2canvas from 'html2canvas';

  export default {
    data() {
      return {
        tableData: [{
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }],
        htmlTitle:"PDF测试"
      }
    },
    methods: {
      async exportPDF() {
        const content = this.$refs.pdfContent;
        const canvas = await html2canvas(content);
        const imgData = canvas.toDataURL('image/png');
        const doc = new jsPDF({
          orientation: 'portrait',
          unit: 'px',
          format: 'a4',
        });
        const imgProps= doc.getImageProperties(imgData);
        const pdfWidth = doc.internal.pageSize.getWidth();
        const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
        doc.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
        doc.save('导出pdf测试1.pdf');
      },
       exportPDF2() {
        html2canvas(document.querySelector('#pdfDom'), {
            allowTaint: false,        // 是否允许跨域图像。会污染画布,导致无法使用canvas.toDataURL 方法
            backgroundColor: '#fff',  // 画布背景色(如果未在DOM中指定)。设置null为透明
            useCORS: true,            // 是否尝试使用CORS从服务器加载图像
            dpi: 500,                 // 导出pdf清晰度
            scale: window.devicePixelRatio, // 用于渲染的比例。默认为浏览器设备像素比率。
          }
        ).then(function (canvas) {
            var imageData = canvas.toDataURL('image/jpeg', 1.0); // html生成图片的数据
            const canvasWidth = canvas.width;  // 原本的html页面的宽高
            const canvasHeight = canvas.height;
            // 当分辨率是72像素/英寸时,A4纸像素长宽分别是842×595
            var a4Width = 595;                                  // A4 宽度
            var a4Height = (595 / canvasWidth) * canvasHeight;  // A4总高度
            let pageHeight = canvasWidth / 595 * 842;           // 生成pdf的一页显示html的高度
            let restHeight = canvasHeight;                      // 未生成pdf的html页面高度,最初是整体的高度
            var position = 0;                                   // 页面上下偏移的大小
            /**
             * 参数1:方向:l:横向  p:纵向
             * 参数2:单位:"pt"、"mm"、"cm"、"m"、"in"、"px"
             * 参数3:格式:默认为a4
             */
            var pdf = new jsPDF('p', 'pt', 'a4');
            if (restHeight < pageHeight) {                     // 当内容未超过pdf一页显示的范围,无需分页
              /**
               * 将图像添加到PDF中
               * 参数1:图片的url
               * 参数2:图片的格式
               * 参数3:图片上下偏移的大小
               * 参数4:原始宽度
               * 参数5:原始高度
               */
              pdf.addImage(imageData, 'JPEG', 0, position, a4Width, a4Height);
            } else {
              while (restHeight > 0) {
                pdf.addImage(imageData, 'JPEG', 0, position, a4Width, a4Height)
                restHeight -= pageHeight;
                position -= 842;
                if (restHeight > 0) {
                  pdf.addPage();      // 在PDF文档中添加新页面
                }
              }
            }
            pdf.save("导出pdf测试2" + '.pdf')
          }
        )
      },
    },
  };
</script>
<style>
  .mmm {
    background: linear-gradient(to right, #39fad7, #f9faa1,#39fad7); /* 标准的语法 */
  }
</style>

3.1 demo1

源码中 【导出PDF】按钮,不会分页导出,会截断数据,适用于只需要导出一页的数据,如证件、行数少的表格数据等。

3.2 demo2

源码中 【导出PDF2】按钮,会分页导出,实际应用中根据需求进行处理、设置。

3.3 demo3

源码中 【导出PDF3】按钮,会分页导出,封装了方法,本质和【导出PDF2】按钮一样。

<el-button type="primary" @click="getPdf()" >导出PDF3

此按钮为封装方法,所以当前源码搜不到。

1)、在utils文件夹中创建htmlToPdf.js的文件,如下:

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default{
  install (Vue, options) {
    Vue.prototype.getPdf = function () {
      var title = this.htmlTitle
      html2Canvas(document.querySelector('#pdfDom'), {
        allowTaint: true
      }).then(function (canvas) {
          let contentWidth = canvas.width
          let contentHeight = canvas.height
          let pageHeight = contentWidth / 592.28 * 841.89
          let leftHeight = contentHeight
          let position = 0
          let imgWidth = 595.28
          let imgHeight = 592.28 / contentWidth * contentHeight
          let pageData = canvas.toDataURL('image/jpeg', 1.0)
          let PDF = new JsPDF('p', 'pt', 'a4')
          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()
              }
            }
          }
          PDF.save(title + '.pdf')
        }
      )
    }
  }
}

2)、在main.js中注册自定义的插件htmlToPdf.js

3)、方法、属性解释及导出文件

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

htmlTitle:"PDF测试" //主页面中定义文件名称,htmlToPdf.js中获取。

相关推荐
m0_748255264 小时前
前端安全——敏感信息泄露
前端·安全
鑫~阳5 小时前
html + css 淘宝网实战
前端·css·html
Catherinemin5 小时前
CSS|14 z-index
前端·css
2401_882727577 小时前
低代码配置式组态软件-BY组态
前端·后端·物联网·低代码·前端框架
NoneCoder7 小时前
CSS系列(36)-- Containment详解
前端·css
anyup_前端梦工厂7 小时前
初始 ShellJS:一个 Node.js 命令行工具集合
前端·javascript·node.js
5hand7 小时前
Element-ui的使用教程 基于HBuilder X
前端·javascript·vue.js·elementui
GDAL8 小时前
vue3入门教程:ref能否完全替代reactive?
前端·javascript·vue.js
六卿8 小时前
react防止页面崩溃
前端·react.js·前端框架
z千鑫8 小时前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js