实际开发需求: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. 微服务开发平台 Spring Cloud Blade 部署实践

    本文介绍使用 Rainbond 快速部署 Spring Cloud Blade 微服务平台.Spring Cloud Blade 是一个由商业级项目升级优化而来的微服务架构,采用Spring Boot ...

  2. 一次TiDB GC阻塞引发的性能问题分析

    背景 前不久从项目一线同学得到某集群的告警信息,某个时间段 TiDB duration 突然异常升高,持续时间6小时左右,需要定位到具体原因. 分析过程 第一招,初步判断 由于项目条件苛刻,历经苦难才 ...

  3. vivo 低代码平台【后羿】的探索与实践

    作者:vivo 互联网前端团队- Wang Ning 本文根据王宁老师在"2022 vivo开发者大会"现场演讲内容整理而成.公众号回复[2022 VDC]获取互联网技术分会场议题 ...

  4. vue3+TS 自定义指令:长按触发绑定的函数

    vue3+TS 自定义指令:长按触发绑定的函数 而然间看到一个在vue2中写的长按触发事件的自定义指定,想着能不能把他copy到我的vue3项目中呢. 编写自定义指令时遇到的几个难点 1.自定义指令的 ...

  5. java中json字符串与实体类对象相互转换

    1.问题描述 有一个需求是这样的,把实体类转为Json字符串存入redis中,然后再把redis中存放的实体类Json字符串插入数据库中.因此需要涉及到json字符串与实体类对象的相互转换. 2.产生 ...

  6. 使用xshell连接linux虚拟机

    目录 1.涉及的软件 2.连接步骤 2.1.虚拟机网络连接设置 2.2.配置linux的ip地址 2.3.关闭linux的防火墙 2.4.启动ssh服务 2.5.使用xshell连接linux 1.涉 ...

  7. Web3区块链DAS域名注册教程 tron trx链波卡钱包地址解析 用户名转账 ENS

    而在去中心化系统中,大部分人充值.转账时,使用的都是区块链原生的长地址,比如: ETH 的地址: 0x9euo8sHip*******dHld90 CKB 的地址: ckHUEI829D******* ...

  8. ★k倍区间【第八届蓝桥杯省赛C++B组,第八届蓝桥杯省赛JAVAB组】

    k倍区间 给定一个长度为 \(N\) 的数列,\(A1,A2,-AN\),如果其中一段连续的子序列 \(Ai,Ai+1,-Aj\) 之和是 \(K\) 的倍数,我们就称这个区间 \([i,j]\)是 ...

  9. KMP 与 Z 函数

    \(\text{By DaiRuiChen007}\) 一.KMP 算法 I. 问题描述 在文本串 \(S\) 中找到模式串 \(T\) 的所有出现,其中 \(|S|=n,|T|=m\) II. 前置 ...

  10. 图文并茂quasar2.6+vue3+ts+vite创建项目并引入mockjs,mockjs 拦截ajax请求的原理是什么,quasar为什么要使用boot?

    每天都要开心(▽)哇: 首先呢,我们来创建项目 执行下面命令,开始创建项目啦 $ npm i -g @quasar/cli $ npm init quasar 下面是我的选项,仅供参考哇 √ What ...