Vue中 前端实现生成 PDF 并下载

Vue中 前端实现生成 PDF 并下载

文章资讯baisoukeji2021-10-16 16:22:013620A+A-

思路: 通过 html2canvas 将 HTML 页面转换成图片,然后再通过 jspdf 将图片的 base64 生成为 pdf 文件。

1. 安装及引入

// 将页面 html 转换成图片npm install html2canvas --save  // 将图片生成 pdfnpm install jspdf --save复制代码

在项目主文件 main.js 中引入定义好的实现方法并注册

import htmlToPdf from '@/utils/htmlToPdf';// 使用 Vue.use() 方法就会调用工具方法中的install方法Vue.use(htmlToPdf);复制代码

2. 封装导出 pdf 文件方法

配置详解

let pdf = new jsPDF('p', 'pt', [pdfX, pdfY]);
第一个参数: l:横向  p:纵向
第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px");
第三个参数:可以是下面格式,默认为“a4”。如需自定义格式,只需将大小作为数字数组传递,如:[592.28, 841.89];
		   a0 - a10
		   b0 - b10
		   c0 - c10
  		   dl
		   letter
		   government-letter
		   legal
		   junior-legal
		   ledger
		   tabloid
		   credit-card复制代码

pdf.addPage() 在PDF文档中添加新页面,默认a4。参数如下:

Vue中 前端实现生成 PDF 并下载 新闻 第1张

pdf.addImage() 将图像添加到PDF。参数如下:

Vue中 前端实现生成 PDF 并下载 新闻 第2张

删除某页 pdf

let targetPage = pdf.internal.getNumberOfPages(); //获取总页pdf.deletePage(targetPage); // 删除目标页复制代码

保存 pdf 文档

pdf.save(`测试.pdf`);复制代码

Vue中 前端实现生成 PDF 并下载 新闻 第3张

封装导出 pdf 文件方法(utils/htmlToPdf.js)

// 导出页面为PDF格式import html2Canvas from 'html2canvas'import JsPDF from 'jspdf'export default{
  install (Vue, options) {
    Vue.prototype.getPdf = function () {      // 当下载pdf时,若不在页面顶部会造成PDF样式不对,所以先回到页面顶部再下载
      let top = document.getElementById('pdfDom');      if (top != null) {
        top.scrollIntoView();
        top = null;
      }      let title = this.exportPDFtitle;
      html2Canvas(document.querySelector('#pdfDom'), {        allowTaint: true
      }).then(function (canvas) {        // 获取canvas画布的宽高
        let contentWidth = canvas.width;        let contentHeight = canvas.height;	      // 一页pdf显示html页面生成的canvas高度;
        let pageHeight = contentWidth / 841.89 * 592.28;	      // 未生成pdf的html页面高度
        let leftHeight = contentHeight;	      // 页面偏移
        let position = 0;	      // html页面生成的canvas在pdf中图片的宽高(本例为:横向a4纸[841.89,592.28],纵向需调换尺寸)
        let imgWidth = 841.89;        let imgHeight = 841.89 / contentWidth * contentHeight;        let pageData = canvas.toDataURL('image/jpeg', 1.0);        let PDF = new JsPDF('l', 'pt', 'a4');        // 两个高度需要区分: 一个是html页面的实际高度,和生成pdf的页面高度
        // 当内容未超过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 -= 592.28;            // 避免添加空白页
            if (leftHeight > 0) {
              PDF.addPage();
            }
          }
        }
        PDF.save(title + '.pdf')
      })
    }
  }
}复制代码

相关组件中应用

<template>  <div  >
    <div id="pdfDom" >
      <el-table
        :data="tableData"
        border>
        <el-table-column prop="date" label="日期" width="250"></el-table-column>
        <el-table-column prop="name" label="姓名" width="250"></el-table-column>
        <el-table-column prop="address" label="地址"></el-table-column>
      </el-table>
    </div>
    <button type="button"  @click="btnClick">导出PDF</button>
  </div></template> 
<script>export default {  data() { 
    return {      exportPDFtitle: "页面导出PDF文件名",      tableData: [
         {          date: '2016-05-06',          name: '王小虎',          address: '重庆市九龙坡区火炬大道'
        }, {          date: '2016-05-07',          name: '王小虎',          address: '重庆市九龙坡区火炬大道'
        },{          date: '2016-05-03',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-02',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-04',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-01',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-08',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-07',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-01',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-08',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-07',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '南京市江宁区将军大道'
        }, {          date: '2016-05-07',          name: '王小虎',          address: '南京市江宁区将军大道'
        },, {          date: '2016-05-04',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-01',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-08',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-07',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        },{          date: '2016-05-01',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-08',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '上海市普陀区金沙江路 1518 弄'
        }, {          date: '2016-05-08',          name: '王小虎',          address: '武汉市洪山区文化大道'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '武汉市洪山区文化大道'
        }, {          date: '2016-05-07',          name: '王小虎',          address: '武汉市洪山区文化大道'
        }, {          date: '2016-05-06',          name: '王小虎',          address: '南京市江宁区将军大道'
        }, {          date: '2016-05-07',          name: '王小虎',          address: '武汉市洪山区文化大道'
        },
      ]
    } 
  }, 
  methods: {    btnClick(){      this.$nextTick(() => {this.getPdf();})
    },
  },  
}</script>  复制代码

效果

Vue中 前端实现生成 PDF 并下载 新闻 第4张

待优化部分

  1. 分页时,页面内容被截断(欢迎留言讨论交流);

  2. 不同内容,另起一页开始;思路:计算超出内容,占最后一页的高度(设定间距 = 页面高度 - 超出部分高度)。


Copyright 中文社区 版权所有 精品源码推荐:http://github.crmeb.net/u/defu
#转载请注明出处!

点击这里复制本文地址 以上内容由开源世界整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

开源世界-开源独尊-开源中国-ThinkPHP-CRMEB-商城源码-项目下载站-CMS企业模板-互站网-悟空源码-A5资源网-CSDN-ASP300 © All Rights Reserved.  Copyright 开源世界 版权所有
Powered by 百搜科技 Themes by www.baisou.ltd
联系我们| 关于我们| 留言建议| 网站管理

分享:

支付宝

微信

嘿,欢迎咨询
请先 登录 再评论,若不是会员请先 注册