Skip to content

❤vue中pdf导出的实现和使用

1、pdf的认识

在前端生成pdf的过程之中,有很多插件都为我们提供了类似的功能,接下来我们简单看看具体有哪些部分可以帮助我们呢实现。

前端 PDF 生成与浏览器的 API 调用有关,JavaScript有很多相关库可以使用这些 API 来完成。

这里我们可以简单看看这个清单:

生成pdf的方式:

  • jsPDF
  • html2pdf
  • pdfmake
  • PDFsKit
  • ReLaXed
  • nodeice
  • Electron
  • PDFObject
  • pdf2json

转化pdf文件我们需要用到两个东西html2canvasjspdf,先来看看这个工具都分别用来做什么的

html2canvasjspdf都是用于处理网页截图和生成 PDF 文件的工具库。

(1)html2canvas:

作用:

  • html2canvas 是一个 JavaScript 库,用处就是将当前页面的 DOM 元素转换为 Canvas。它可以捕获整个页面或特定的 DOM 元素,并生成一个 Canvas 元素,之后我们可以将其导出为图像文件(如 PNG 或 JPEG)或者直接插入到 PDF 文件中以便后续导出成pdf(注意,这里是只能生成图片,而不能生成pdf文件的)。

根据它的这个特性,我们也可以发现他的一些用途::

  • 截图: 实现网页截图功能,将网页内容保存为图片。
  • 导出图像:将 Canvas 导出为图片文件。
  • PDF 生成:将Canvas 直接用于 PDF 文件的生成,也就是把网页内容变成一个 PDF 文档。

(2) jspdf

作用:

jspdf 是一个 JavaScript 库,用于在客户端生成 PDF 文件。这个库为我们提供了一组 API 来创建和操作 PDF 文件,包括添加文本、图像、表格等内容到 PDF 页面中。

主要用途:

  • PDF 生成: 主要用于在客户端动态生成 PDF 文档。通过 JavaScript 代码生成包含动态内容的 PDF 文件,例如报表、文档或者将网页内容转换为 PDF。
  • 打印: 可以将生成的 PDF 文件直接打印出来,或者在浏览器中下载保存。

通过上面的介绍我们可以发现,他们最主要的作用,其实就是帮助我们生成pdf文件或者图片

  • html2canvas 用于将网页内容截图并转换为 Canvas,方便导出为图片或者用于 PDF 生成。
  • jspdf 用于在客户端生成和操作 PDF 文件,通过 JavaScript 动态生成 PDF,添加多种元素和格式化内容。

接下来我们就看看具体在vue3的项目之中我们应该如何使用他们

2、依赖安装和使用

接下来我们在我们的项目之中进行安装、导入和引入

js
yarn add html2canvas
yarn add jspdf

安装成功以后可以看看砸门的版本号,我这里版本号是

js
"html2canvas": "^1.4.1",
"js-cookie": "^3.0.5",

然后我们搭建一下我们的pdf界面,这里我们就随便找个文件,然后搭建一下

👉 接下来我们简单使用一下pdf

js
// 写个导出按钮部分
<div class="btn" @click="getPdf">导出pdf</div>


//先把结构写一个给定宽高

<div class="resume_detail_box page_common_padding" id="pdfDom"></div>


// 然后我们在其中导入要使用的部分

// 页面导出为pdf格式
import html2Canvas from 'html2canvas';
import jsPDF from 'jspdf';
import { ref, onMounted } from "vue";

// 这里我们简单写个导出方法
const getPdf= () => {
		let ele = document.querySelector('#pdfDom');
	    let eleWidth = ele.offsetWidth;
	    let eleHeight = ele.offsetHeight;
	    const canvas = html2Canvas(ele, {
	      allowTaint: true,
	      useCORS: true,
	      scale: 2, // 提升画面质量,但是会增加文件大小
	    }).then((canvas)=>{
	    	 let pdf
		    let pdfWidth
		    let pdfHeight
		    // 判断横版 || 竖版
		    if (eleWidth > eleHeight) {
		      pdf = new jsPDF("l", "pt", "a4");
		      pdfWidth = 841.89;
		      pdfHeight = 595.28;
		    } else {
		      pdf = new jsPDF("0", "pt", "a4");
		      //pdf页面偏移
		      pdfWidth = 595.28;
		      pdfHeight = 841.89;
		    }
		    let position = 0;
		    const imgData = canvas.toDataURL("image/jpeg", 1.0);
		    pdf.addImage(imgData, "JPEG", 0, position, pdfWidth, pdfHeight);
		    pdf.save("报告"+".pdf");
	    });
}

点击导出,这个时候我们发现,已经可以完美进行导出了!查看一下我们导出的效果!

3、pdf详细使用

添加分页,多页导出切换

👉vue3使用案例

JS
<template>
  <div>
    <div ref="content" class="content">
      <h1>Vue 3 导出 PDF 示例</h1>
      <p>这是一个示例内容,将被导出为 PDF 文件。</p>
    </div>
    <button @click="exportPDF">导出 PDF</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

const content = ref(null);  // 用来引用需要导出的内容

// 导出 PDF 文件
const exportPDF = () => {
  html2canvas(content.value).then((canvas) => {
    // 获取 Canvas 数据
    const imgData = canvas.toDataURL('image/png');
    
    // 创建 PDF 实例
    const doc = new jsPDF();
    
    // 将生成的 Canvas 图像添加到 PDF 中
    doc.addImage(imgData, 'PNG', 10, 10);
    
    // 保存为 PDF 文件
    doc.save('document.pdf');
  });
};
</script>

<style scoped>
.content {
  padding: 20px;
  border: 1px solid #ccc;
  background-color: #f9f9f9;
}

button {
  margin-top: 20px;
  padding: 10px 20px;
  background-color: #4CAF50;
  color: white;
  border: none;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}
</style>

4、问题以及处理

这部分主要记录📝在HTMl网页导出成为PDF文件的过程之中遇到的问题

(1) 渐变色背景处理

首先要知道,在我们的处理pdf的过程之中,pdf渐变色是完全不生效的,所以这个过程之中很容易就导致出现这种问题。

(2)排列布局的样式写法不生效

我们写的格局是这样子的:

image.png

这种样式写法导致的问题

js
// 刚刚开始采用的是上面的这种写法,但是导出一直不显示文字,这个时候我有点懵,一度以为是宽度问题 
display:incline-block;


后来发现:被迫只能将写法=改成以下这种:
父:display:flex;
子:flex:1

image.png

(3)echarts雷达图大小问题

图表上面是遮掩这样子的

image.png

实际上导出以后存在的样式问题,字体变得非常大

image.png

  • 解决圆圈大小问题

首先就是调整: option => radar=> radius 大小,这个直接解决了我大小圆圈问题

  • 解决文字大小问题

👉 采用官方给我们提供的文字默认大小是非常大的,这里应该自定义文字大小

js
name: {
    textStyle: {
        fontSize: 13,  // 设置外圈文字的字体大小
    }
},

解决效果:

👉导出的时候依然存在文字遮挡,这里换个思路,就是我给外层容器加padding来进行解决,让文字在padding之中

👉 echarts雷达图遮挡问题进一步处理

调整雷达图文字距离雷达图的距离

js
nameGap: 2,

👉调整雷达图大小

这里最后成功解决!

(4) echarts折线图大小处理

image.png

这里折现正常,但是打印出之后,我们可以发现,字体变得特别特别大,这里我们设置一下折线图得legend文字大小

js
  legend: {
    data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine'],
    textStyle: {
            fontSize: 13 // 设置图例文字的字体大小
        },
  },

(5)echarts折线图文字遮挡问题

我们正常是这样子

image.png

转为pdf之后出现了文字遮挡的情况

image.png

最好的解决办法就是调整底部

js
grid: {
  top: '8%',
  left: '3%',
  right: '3%',
  bottom: '18%',
  containLabel: true
},

(6)echarts折线图文字过长

js
// 调整文字
axisLabel: {
    //展示角度
    rotate: 0,
    show: true,
    textStyle: { color: '#385C8B' },
    fontSize: 12,
    formatter: function (value) {
        if (value.length > 3) {
            // 如果文字长度超过三个字,进行换行处理
            return value.substring(0, 3) + dataunit + '\n' + value.substring(3)+ dataunit;
        } else {
            return value + dataunit;
        }
    }
  }
  
// 调整距离
// 设置上下左右边距
grid: {
  top: '5%',
  left: '14%',
  right: '4%',
  bottom: '16%',
  containLabel: true
},

Released under the MIT License.