Vue页面生成PDF的最佳方法推荐

 更新时间:2022年05月24日 10:04:35   作者:愤怒小绵羊  
公众中经常会有这种场景,一些合同、协议等的页面需要进行下载,而且需要和页面保持一致,下面这篇文章主要给大家介绍了关于Vue页面生成PDF的最佳方法,需要的朋友可以参考下

前言

最近项目有个需求,将系统统计的数据生成分析报告,然后可以导出成PDF。

这种方法可以有两种,一种是直接调用打印,用户通过浏览器提供的打印页面手动选择导出PDF。当然这种方式兼容性差,且体验不好,显然不是我们想要的效果。

那么第二种方法的实现思路是什么呢?

首先生成报告页面,也就是常规页面;

然后将页面转换成图片( 用到的组件 html2canvas );

最后将图片导出成PDF( 用到的组件 jspdf )。

安装依赖

npm install --save html2canvas  // 页面转图片
npm install jspdf --save  // 图片转pdf

页面转图片

新建一个 index.vue 页面:

<template>
  <div ref="pdf">
    这是待转换的页面,点击 
    <button @click="handleExport">导出</button> 按钮,完成导出操作。
  </div>
</template>

<script>
import {downloadPDF} from "@/util/pdf.js"  //工具方法,导出操作
export default {
  name: "pdf",
  data() {
    return {};
  },
  methods: {
    handleExport(){
      downloadPDF(this.$refs.pdf)
    }
  }
};
</script>

页面很简单,一段话加上一个导出按钮。整个页面被设置别名 (ref=“pdf”),导出的时候通过别名导出整个页面。

按钮点击事件中调用了一个工具方法 downloadPDF(),来自于工具类 pdf.js:

import html2canvas from "html2canvas";

export const downloadPDF = page => {
  html2canvas(page).then(function(canvas) {
    page.appendChild(canvas);
  });
};

也很简单,首先引入了 html2canvas,定义downloadPDF方法,接受一个参数就是要导出的内容,可以使用id获取,也可以使用 ref 。

运行结果:

当我们点击导出按钮后,在现有的页面增加了一行相同的内容。通过元素检查器可以看到增加的这行内容实际是一个 canvas 图像,里面的按钮已经不可以操作了。

这样,页面转换图片的过程就完成了。

图片转PDF

首先给index.vue改造一下,为了让我们导出的pdf好看一点,使用el-table做个表格,其它的导出逻辑不变:

<template>
  <div ref="pdf">
    
    <el-table
      :data="tableData"
      style="width: 700px">
      <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>

    <button @click="handleExport">导出</button>
  </div>
</template>
<script>
import {downloadPDF} from "@/util/pdf.js"  //工具方法,导出操作
export default {
  name: "pdf",
  data() {
    return {
      
          tableData: [{
            date: '昨天',
            name: '刘德华',
            address: '你好帅'
          }, {
            date: '今天',
            name: '郭富城',
            address: '你最帅'
          }, {
            date: '明天',
            name: '张学友',
            address: '你贼帅'
          }, {
            date: '每天',
            name: '黎明',
            address: '我没你帅'
          }]
    };
  },
  methods: {
    handleExport(){
      downloadPDF(this.$refs.pdf)
    }
  }
};
</script>

效果图:

然后改造一下pdf.js,增加上pdf转换逻辑

import html2canvas from "html2canvas";
import jsPDF from "jspdf";

export const downloadPDF = page => {
  html2canvas(page).then(function(canvas) {
    canvas2PDF(canvas);
  });
};

const canvas2PDF = canvas => {
  let contentWidth = canvas.width;
  let contentHeight = canvas.height;
  
  let imgHeight = contentHeight;
  let imgWidth = contentWidth;

  // 第一个参数: l:横向  p:纵向
  // 第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px")
  let pdf = new jsPDF("l", "pt");

  pdf.addImage(
    canvas.toDataURL("image/jpeg", 1.0),
    "JPEG",
    0,
    0,
    imgWidth,
    imgHeight
  );

  pdf.save("导出.pdf");
};

canvas2PDF 方法中创建了jsPDF的实例,然后添加上一步生成的图片,最后保存导出pdf文件。

导出的文件效果:

A4打印适配

因为部分需求有需要生成的页面使用A4纸打印,那么pdf生成时的宽高尺寸就不能像上面一样设定。需要按照A4纸的尺寸比例调整(其它打印需求同理,使用对应纸张比例即可)

那么改造一下 pdf.js

import html2canvas from "html2canvas";
import jsPDF from "jspdf";

export const downloadPDF = page => {
  html2canvas(page).then(function(canvas) {
    canvas2PDF(canvas);
  });
};

const canvas2PDF = canvas => {
  let contentWidth = canvas.width;
  let contentHeight = canvas.height;

  //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
  let imgWidth = 595.28;
  let imgHeight = 592.28/contentWidth * contentHeight;

  // 第一个参数: l:横向  p:纵向
  // 第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px")
  let pdf = new jsPDF("p", "pt");

  pdf.addImage(
    canvas.toDataURL("image/jpeg", 1.0),
    "JPEG",
    0,
    0,
    imgWidth,
    imgHeight
  );

  pdf.save("导出.pdf");
};

这里面将 imgWidth 和 imgHeight 按照A4纸比例调整后,导出的pdf就可以正常比例打印了。

总结

到此这篇关于Vue页面生成PDF的文章就介绍到这了,更多相关Vue页面生成PDF内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决vue-cli 配置资源引用的绝对路径问题

    解决vue-cli 配置资源引用的绝对路径问题

    这篇文章主要介绍了vue-cli 配置资源引用的绝对路径的问题,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • Vue中props的使用详解

    Vue中props的使用详解

    props属性是父子组件之间的通信桥梁。这篇文章主要介绍了Vue中props的使用,需要的朋友可以参考下
    2018-06-06
  • vue中node_modules中第三方模块的修改使用详解

    vue中node_modules中第三方模块的修改使用详解

    这篇文章主要介绍了vue中node_modules中第三方模块的修改使用,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • VUE路由动态加载实例代码讲解

    VUE路由动态加载实例代码讲解

    在本文里小编给大家整理了关于VUE路由动态加载实例代码以及相关知识点,需要的朋友们学习下。
    2019-08-08
  • html2canvas使用文档(vue举例)

    html2canvas使用文档(vue举例)

    html2canvas.js是一款可以在网页上实现页面截图的js,它使用了html5和css3的一些新功能特性,实现了在客户端对网页进行截图的功能,这篇文章主要给大家介绍了关于html2canvas使用的相关资料,需要的朋友可以参考下
    2024-03-03
  • Vue实现简单搜索功能的示例代码

    Vue实现简单搜索功能的示例代码

    在vue项目中,搜索功能是我们经常需要使用的一个场景,最常用的是在列表数据中搜索一个想要的,今天的例子就是我们实现vue从列表数据中搜索,希望对大家有所帮助
    2023-03-03
  • Vue中watch与watchEffect的区别详细解读

    Vue中watch与watchEffect的区别详细解读

    这篇文章主要介绍了Vue中watch与watchEffect的区别详细解读,watch函数与watchEffect函数都是监听器,在写法和用法上有一定区别,是同一功能的两种不同形态,底层都是一样的,需要的朋友可以参考下
    2023-11-11
  • 详解vue-cli多页面工程实践

    详解vue-cli多页面工程实践

    本篇文章主要介绍了详解vue-cli多页面工程实践,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 关于Vue单页面骨架屏实践记录

    关于Vue单页面骨架屏实践记录

    这篇文章主要给大家介绍了关于Vue单页面骨架屏实践的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-12-12
  • vue中v-html妙用及空白行消除方式

    vue中v-html妙用及空白行消除方式

    这篇文章主要介绍了vue中v-html妙用及空白行消除方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04

最新评论