实际开发需求:vue项目中,根据数据结构生成echarts图表组件,生成带有样式的图表以后,点击下载按钮,把图表以pdf格式的文件下载到本地

实现思路:将vue界面的echarts组件生成图片,然后使用插件将生成的图片放入pdf中,再实现pdf文件的下载

涉及框架以及插件:vue、echarts、html2canvas、dom-to-image、jspdf

插件介绍:

vue、echarts 不用多说,vue前端的框架,echarts用来根据数据生成的带有样式效果的图表;html2canvas与dom-to-image都是将界面上的dom生成图片。

html2canvas

能够实现在用户浏览器端直接对整个或部分页面进行生成图片,主要是将选中的页面或者整个页面渲染成一个canvas图片,通过读取DOM并将不同的样式应用到这些元素上实现。可以通过获取HTML的某个元素,然后生成Canvas,从而生成图片。

安装
npm install --save html2canvas
或 yarn add html2canvas
引入
import html2canvas from 'html2canvas';

用法:

<div class="container" id="myDom1">
测试
</div>
<style>
.container {
width:100px;
height:100px;
background:red;
color: #ffffff;
}
</style>
methods(){
getImage(){
html2canvas(document.querySelector("#myDom1")).then(canvas => {
console.logo(canvas)
document.body.appendChild(canvas);
var dataUrl = canvas.toDataURL("image/png")
});
}
}
参数名称 类型 默认值 描述
allowTaint boolean false 允许跨域
background string #fff canvas的背景颜色,如果没有设定默认透明
height number null canvas高度设定
letterRendering boolean false 在设置了字间距的时候有用
logging boolean false 输出信息
proxy string undefined 代理地址
taintTest boolean true 是否在渲染前测试图片
timeout number 0 图片加载延迟,默认延迟为0,单位毫秒
width number null canvas的宽度
useCORS boolean false 图片跨域问题

dom-to-image

它可以将任意DOM节点转换成用JavaScript编写的矢量(SVG)或光栅(PNG或JPEG)图像。

安装
npm install dom-to-image
或 yarn add dom-to-image
引入
import domtoimage from 'dom-to-image';
或 var domtoimage = require('dom-to-image');

基本用法:

<template>
<div id=""myDom>
<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>
......
</div>
</template>
methods(){
getDomToImage(){
let dom = document.getElementById('myDom');
domtoimage.toPng(dom).then(function (dataUrl) {
var img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
})
.catch(function (error) {
console.error('wrong!', error);
});
}
}

获取一个png的blob:

domtoimage.toBlob(document.getElementById('myDom')).then(function (blob) {
console.log(blob)
});

jspdf

jsPDF 是一个使用 Javascript 语言生成 PDF 的开源库。你可以在 Firefox 插件,服务端脚本或是浏览器脚本中使用它。

安装:
npm install jspdf
或 yarn add jspdf
引入
import jsPDF from "jspdf"

基本用法:

let pdf = new jsPDF('p', 'pt', 'a4);
参数1:l:横向 p:纵向
参数2:单位("pt","mm", "cm", "m", "in" or "px")
参数3:格式,默认为“a4”

常用方法:

pdf.addPage()  在PDF文档中添加新页面,参数如下,也可以不设置,默认a4
pdf.addImage() 将图像添加到PDF中
pdf.save(`保存的PDF文件.pdf`); 保存为pdf格式的文件

回到需求:vue项目中,根据数据结构生成echarts图表组件,生成带有样式的图表以后,点击下载按钮,把图表以pdf格式的文件下载到本地(带分页),部分代码如下(思路)

1.使用html2canvas
<template>
<div id="pdfDom" ref="pdfDom">
// 此处存放界面中显示的内容区域,生成pdf的内容区域......
</div>
</template> methods(){
let node = document.getElementById('pdfDom');
html2canvas(document.getElementById('pdfDom'), {
scale: 2
}).then(function (canvas) {
var pdfWidth = canvas.width;
var pdfHeight = canvas.height;
var pageHeight = pdfWidth / 592.28 * 841.89;
var leftHeight = pdfHeight;
var position = 0;
var imgWidth = 595.28;
var imgHeight = 595.28 / pdfWidth * pdfHeight;
var pageData = canvas.toDataURL("img/jpeg", 1.0);
var pdf = new jsPDF('', 'pt', 'a4');
// 判断打印dom高度是否需要分页,如果需要进行分页处理
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()
}
}
}
const aLink = document.createElement('a')
document.body.appendChild(aLink)
const url = URL.createObjectURL(_this.toBlob(pdf.output('datauristring')))
aLink.href = url
let date = new Date()
let year = date.getFullYear()
let month = (date.getMonth() + 1).toString().padStart(2, 0)
let day = date.getDate().toString().padStart(2, 0)
let hour = date.getHours().toString().padStart(2, 0)
let minutes = date.getMinutes().toString().padStart(2, 0)
let seconds = date.getSeconds().toString().padStart(2, 0)
aLink.download = '保存的PDF文件-' + '.pdf'
aLink.click()
window.URL.revokeObjectURL(url)
})
}
2.使用dom-to-image
<template>
<div id="pdfDom" ref="pdfDom">
// 此处存放界面中显示的内容区域,生成pdf的内容区域......
</div>
</template> methods(){
let node = document.getElementById('pdfDom');
domtoimage.toJpeg(node, {
width: node.clientWidth,
height: node.clientHeight,
cacheBust: true,
style: {
margin: 0,
background: '#fff',
}
}).then(function (dataUrl) {
console.log(node.clientWidth)
that.canvasWidth = node.clientWidth;
that.canvasHeight = node.clientHeight;
let imgObj = new Image()
imgObj.src = dataUrl;
document.documentElement.scrollTop = 0
//待图片加载完后,将其显示在canvas上
imgObj.onload = function (img) {
let canvas = document.getElementById("canvasDom");
console.log(canvas.width, canvas.height, 'canvas.width')
canvas.getContext("2d").drawImage(imgObj, 0, 0, that.canvasWidth, that.canvasHeight); //将图片绘制到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('', 'pt', 'a4')
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) // 大于1页高度时分页
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
const aLink = document.createElement('a')
document.body.appendChild(aLink)
const url = URL.createObjectURL(that.toBlob(PDF.output('datauristring')))
aLink.href = url
let date = new Date()
let year = date.getFullYear()
let month = (date.getMonth() + 1).toString().padStart(2, 0)
let day = date.getDate().toString().padStart(2, 0)
let hour = date.getHours().toString().padStart(2, 0)
let minutes = date.getMinutes().toString().padStart(2, 0)
let seconds = date.getSeconds().toString().padStart(2, 0)
aLink.download = '保存的PDF文件-' + '.pdf'
aLink.click()
window.URL.revokeObjectURL(url)
}
return dataUrl
})
.catch(function (error) {
console.error('wrong!', error);
});
}

vue前端实现将页面显示内容生成pdf文件的几种方法,html2canvas、dom-to-image、jspdf(带分页)基本使用以及介绍的更多相关文章

  1. 前端axios请求二进制数据流转换生成PDF文件空白问题(终极解决方案)

    本文章共1570字,预计阅读时间1 - 3分钟. 问题场景: axios请求二进制数据转换生成PDF空白问题,使用axios请求后端接口,后端返回的二进制流文件,需要转换成PDF,但是在postman ...

  2. .net生成PDF文件的几种方式

    以下为在.net mvc中,生成pdf的几种方式,资料都是在做项目时网上找的 1.使用Microsoft.Office.Interop.Word.dll将word转换为PDF dll可以单独下载,一般 ...

  3. PHP中的生成XML文件的4种方法(转)

    <?xml version="1.0" encoding="utf-8"?> <article> <item> <ti ...

  4. 生成mif文件的几种方法总结

    mif文件就是存储器初始化文件,即memory initialization file,用来配置RAM或ROM中的数据.生成QuartusII11.0可用的mif文件,有如下几种方式: 方法1:利用Q ...

  5. PHP中的生成XML文件的4种方法分享

    生成如下XML串 Xml代码 <?xml version="1.0" encoding="utf-8"?> <article> < ...

  6. 关于java poi itext生成pdf文件的例子以及方法

    最近正在做导出pdf文件的功能,所以查了了一些相关资料,发现不是很完善,这里做一些小小的感想,欢迎各位“猿”童鞋批评指正. poi+itext,所需要的jar包有itext-2.1.7.jar,poi ...

  7. Django(四) 后台管理:创建管理员、注册模型类、自定义管理页面显示内容

    后台管理 第1步.本地化:设置语言.时区 修改project1/settings.py #LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'zh-hans' #设置语言 ...

  8. 将HTML页面自动保存为PDF文件并上传的两种方式(一)-前端(react)方式

    一.业务场景 公司的样本检测报告以React页面的形式生成,已调整为A4大小的样式并已实现分页,业务上需要将这个网页生成PDF文件,并上传到服务器,后续会将这个文件发送给客户(这里不考虑). 二.原来 ...

  9. 前端生成pdf文件之pdfmake.js

    转载:点击查看原文 pdfmake.js是一个简单的生成pdf文件的插件. pdfmake.js     https://files.cnblogs.com/files/s313139232/pdfm ...

  10. Itext生成pdf文件

    来源:https://my.oschina.net/lujianing/blog/894365 1.背景 在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等. ...

随机推荐

  1. TypeScript 之 Type

    Type 描述:全称叫做 '类型别名',为类型字面量提供名称.比 Interface 支持更丰富的类型系统特性. Type 与 Interface 区别 Interface 只能描述对象的形状,Typ ...

  2. Vuex极速入门

    01.什么是Vuex? 1.1.为什么需要状态管理? 在复杂的系统中,我们会把系统按照业务逻辑拆分为多个层次.多个模块,采用组件式的开发方式.而此时不同模块.父子模块之间的通信就成了一个问题. 为了解 ...

  3. 后疫情办公时代——你需要的多人同步协同编辑Demo(可粘贴可撤销)

    新冠病毒的疫情使得在线办公成为了一个常态,这使得在线文档成为了时下的热点.其中在线协同表格是在线文档的重要一个组成部分,纯前端表格在在线协同表格上有着得天独厚的优势:本身已经实现了单人操作在线文档的基 ...

  4. Law of Iterated Expectations & Covariance

    Law of Iterated Expectations \(E[Y] = E_X[E[Y |X]].\) The notation \(E_X[.]\) indicates the expectat ...

  5. 3xx HTTP状态码的终极指南

    前言 如果你在管理一些网站,那么对HTTP重定向的理解对于可靠的网站性能至关重要.在这篇文章中,我们将全面了解一下3xx HTTP状态码,从这里你可以了解它们是如何工作的,如何更好地管理它们,以及它们 ...

  6. (原创)【B4A】一步一步入门01:简介、开发环境搭建、HelloWorld

    一.前言 作者注:絮絮叨叨,可跳过不看. 一直有开发跨平台软件的需求.因为我的主力是C# ,所以当MAUI出现后,我欣喜若狂的开始学习研究.但是经历了两个月左右的时间,我弃坑了,我发现MAUI不是我能 ...

  7. MySQL 中一条 sql 的执行过程

    一条 SQL 的执行过程 前言 查询 查询缓存 分析器 优化器 执行器 数据更新 日志模块 redo log (重做日志) binlog (归档日志) undo log (回滚日志) 两阶段提交 为什 ...

  8. 反射概述-获取字节码Class对象的三种方式

    反射概述 判定结果∶*红色:失败*绿色:成功*一般我们会使用断言操作来处理结果*Assert.assertEquals(期望的结果,运算的结果);补充∶*Before:*修饰的方法会在测试方法之前被自 ...

  9. docker搭建maven私服(nexus3),整合springboot上传下载依赖

    一.前言 我们在JavaWeb开发中必不可少的就是jar包管理-maven,在没有maven之前,都是自己手动下载jar包导入到项目中,非常的繁琐. maven出现之后,又迎来新的问题,对于仓库里人家 ...

  10. Selenium中的option用法实例

    Selenium中的option用法实例 在上一篇文章Selenium中免登录的实现方法一option中我们用到了option,而option的用法是很多的,本文举几个例子 关于无头浏览器,也属于op ...