echarts 图表导出PDF(带滚动条)/图片导出PDF

news2024/12/23 22:45:11

echarts 图表导出PDF[带滚动条]/图片导出PDF

  • 效果展示
  • 提出问题
  • 思考问题
  • 解决问题
  • 导出PDF 里面的页头中文乱码问题
  • 参数说明

效果展示

在这里插入图片描述

提出问题

在开发过程中,有需求是将展示出来的echarts图表导出为pdf
原本我的滚动条是使用echarts图表进行的滚动,但通过了解后得知,echarts图表如果带滚动条,他只能导出当前页的,因为滚动条以外的是还没有加载,无法导出.

如下图所示:
在这里插入图片描述

思考问题

后面通过思考和百度过后得知,可以以一种新的思想去解决:放弃echarts的滚动条,使用div的滚动条,让echarts图表完全的显示出来

如下图所示:
在这里插入图片描述

解决问题

解决这个问题:如何将已经展示出来的完全的图表分页导出PDF

通过了解后,需要下载jspdfhtml2canvas(由于echarts是由canvas标签承载的,所以需要下载html2canvas)

  • 下载插件命令:
    npm install jspdf
    npm install html2canvas
  • .vue文件中引入插件
    import html2Canvas from "html2canvas";
    import jsPDF from "jspdf";
  • 使用!!
    • html
<div style="height: 100%; padding-top: 40px">
	<div class="title">{{ title }}</div>
	<Tooltip content="导出PDF" placement="top-start" class="download">
		<icon custom="iconfont icon-pdfdayin" @click="exportPDF" />
	</Tooltip>
	<div class="workbook-temp" ref="workbookTempRef">
		<div :style="tempStyle" ref="exportContent">
			<component
				ref="componentRef"
				:is="barLineScatter"
				:ispreview="true"
				:visib="visib"
				:chartData="chartData"
				:mark="mark"
			/>
		</div>
	</div>
</div>
  • JS
    this.$refs.componentRef.myChart.getDom().getElementsByTagName("canvas")[0]说明:
    echarts实体获取对应dom标签
	//导出PDF
async exportPDF() {
     //echarts 图表的canvas标签
	const canvas = this.$refs.componentRef.myChart.getDom().getElementsByTagName("canvas")[0];
	//由于我这里是动态的图表,所以使用逻辑判断:l:横向;p:纵向
	const direction = this.chartData.yAxis[0]?.type == "value" ? "l" : "p";
	const filename = '文件名称.pdf';
	const title = "echarts图表名称";
	this.domToPdf(canvas, filename, direction, title);
},
domToPdf(dom, filename, direction, title) {
       //使导出的图表从最头开始
		document.documentElement.scrollTop = 0;
		document.body.scrollTop = 0;
		html2Canvas(dom, {
			allowTaint: true,
			useCORS: true,
		}).then((canvas) => {
		    //创建实体和设定字体颜色
			let pdf = new jsPDF("landscape", "pt");
			pdf.setFontSize(8);
			pdf.setTextColor("#767676");
			pdf.setFont("simhei");
            //用于获取 HTML5 <canvas> 元素的 2D 渲染上下文对象
			let ctx = canvas.getContext("2d");
			ctx.canvas.willReadFrequently = true;

			//PDF 的宽高(-20 和-30 是为了PDF 周边留白)
			let pdfWidth = pdf.internal.pageSize.getWidth() - 20;
			let pdfHeight = pdf.internal.pageSize.getHeight() - 30;
			//echarts图表 的全部宽高
			let contentWidth = canvas.width;
			let contentHeight = canvas.height;
             //PDF高宽比
			let bi = pdfHeight / pdfWidth;
			//图片宽 等比例缩小
			let imgWidth = direction == "p" ? contentWidth : contentHeight / bi; // A4 页面宽度
			//图片高 等比例缩小
			let imgHeight = direction == "l" ? contentHeight : contentWidth * bi;
            // 获取内容宽高与PDF宽高
			let contentRadio = Math.max(contentWidth / pdfWidth, contentHeight / pdfHeight);  //如果小于1 说明导出的图表宽高小于PDF宽高 图要全部图表宽高
			if (contentRadio <= 1) {
				imgWidth = contentWidth;
				imgHeight = contentHeight;
			}
			const radioTmp = Math.min(pdfWidth / imgWidth, pdfHeight / imgHeight);
			// 页面偏移
			let positionX = 0;
			let positionY = 0;

             //高和宽一共有多少
			let iLength = Math.ceil(contentHeight / imgHeight);
			let jLength = Math.ceil(contentWidth / imgWidth);

			for (let i = 0; i < iLength; i++) {
				positionX = 0;
				positionY = i * imgHeight;
				for (let j = 0; j < jLength; j++) {
				    //获取截图所需图片的数据:(位置x,位置y,图片宽,图片高)
					let imageData = ctx.getImageData(positionX, positionY, imgWidth, imgHeight);
                   //将 ImageData 转换为 base64 格式的图片数据
					let base64Img = this.getImageDataDataURL(imageData);

					// 添加页眉(头部居中)
					pdf.text(`${title}`, pdf.internal.pageSize.width / 2, 10, "center");
					//图片(图片base64码,图片类型,起始横轴,起始纵轴,等比缩放宽,等比缩放高)
					pdf.addImage(base64Img, "JPEG", 10, 20, imgWidth * radioTmp, imgHeight * radioTmp);
					//添加页尾(page 页数 of 总页数)(页尾居中)
					pdf.text(
						"page " + (i * jLength + j + 1) + " of " + iLength * jLength,
						pdf.internal.pageSize.width / 2,
						pdf.internal.pageSize.height - 10,
						"center"
					);
					//如果不是最后一页,新增一个PDF页
					if (!(i == iLength - 1 && j == jLength - 1)) pdf.addPage();
					//x轴移动j+1 个图片宽度
					positionX = (j + 1) * imgWidth;
				}
			}

			// 下载操作
			pdf.save(filename);
		});
	},
	// 将 ImageData 转换为 base64 格式的图片数据
	getImageDataDataURL(imageData) {
		let canvasTemp = document.createElement("canvas");
		canvasTemp.width = imageData.width;
		canvasTemp.height = imageData.height;
		canvasTemp.getContext("2d").putImageData(imageData, 0, 0);
		return canvasTemp.toDataURL("image/png");
	},

导出PDF 里面的页头中文乱码问题

1.在C:\Windows\Fonts路径中查找黑体常规字体
在这里插入图片描述
2.打开此网站将字体转base64码
在这里插入图片描述
在这里插入图片描述
3.将文件复制到项目中
在这里插入图片描述
4.引入
import "@/assets/js/simhei-normal.js";
5.设定黑体常规字体
pdf.setFont("simhei");
名称是simhei-normal.js中设定的名字
在这里插入图片描述

参数说明

  • html2Canvas参数说明

    allowTaint:否允许跨域图片绘制
    backgroundColor:指定截图背景颜色
    canvas:指定截图结果输出的Canvas元素,如果不指定,则会创建一个新的Canvas元素
    foreignObjectRendering:指定是否使用ForeignObject绘制,默认为false,使用ForeignObject可以支持复杂的CSS样式和布局,但是在一些浏览器中可能存在性能问题。
    height:指定截图的高度,如果不指定,则使用自动计算的高度。
    ignoreElements:指定忽略哪些DOM元素,可以是选择器表达式、DOM元素数组、或者函数。使用选择器表达式时,可以使用逗号分隔多个选择器;使用函数时,参数为当前DOM节点,返回值为true时会被忽略。
    letterRendering:指定是否开启字形渲染,默认为false。如果设置为true,可能会导致较慢的渲染速度。
    logging:指定是否显示日志信息,默认为false,如果设置为true,则会在控制台输出日志信息。
    proxy:指定代理地址,如果需要跨域截图,则需要指定代理地址,否则会被浏览器拦截。
    scale:指定截图的缩放比例,默认为1,可以设置为其他值来提高图像质量,但会导致截图时间增加。
    useCORS:指定是否使用跨域资源共享(CORS)获取图像,默认为false。
    width:指定截图的宽度,如果不指定,则使用自动计算的宽度。

  • addImage
    pdf.addImage(pageData, "JPEG", 0, 0, imgWidth, imgHeight)

    1. 图象数据
    2. 图象格式:JPEG PNG GIF WEBP BMP
    3. X:PDF 左上角x坐标轴
    4. y:PDF 左上角Y坐标轴
    5. width:图象在PDF文档中显示的宽度
    6. height:图象在PDF文档中显示的高度
    7. 图象别名
    8. 压缩方式:NONE:不压缩 FAST 快速压缩

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/617242.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《人月神话》阅读推荐

用了两周的时间&#xff0c;大致过了一遍。书中讲述的很多方面可能此时并没有很深刻的体会&#xff0c;但是该书的预见性和分析还是很让人钦佩的。书中对项目、产品、程序、程序员等一系列对象的分析是相当精准的。虽然距今已有四十多年&#xff0c;但很多依旧在发生。   书中…

Java设计模式(四)

系列文章目录 UML类图 文章目录 系列文章目录前言一、UML类图二、UML基本介绍三、UML图1.类图—依赖关系(Dependence)2.类图—泛化关系(generalization)3.类图—实现关系(Implementation)4.类图—关联关系(Association)5.类图—聚合关系(Aggregation)6.类图—组合关系(Composi…

分布式(二)-大型网站架构演化发展历程

大型网站架构演化发展历程 大型网站的技术挑战主要来自于庞大的用户&#xff0c;高并发的访问和海量的数据&#xff0c;任何简单的业务一旦需要处理数以 P 计的数据和面对数以亿计的用户&#xff0c;问题就会变得很棘手。大型网站架构主要解决这类问题。 初始阶段的网站架构 …

MinIO 分片上传

文章目录 1.MinIO 简介2.为什么要分片上传&#xff1f;3.实现思路4.具体实现初始化客户端获取分片上传的预签名 URL合并分片中止合并 5.FAQ端口错误协议错误 参考文献 1.MinIO 简介 MinIO 是适用于 AI 的高性能对象存储系统。 MinIO 简单易用。简单性是 EB 级数据基础设施的基…

宝塔配置MySQL队列调度 | ModStart

执行以下操作前提前进入网站根目录&#xff0c;如 cd /www/wwwroot/xxx.com执行 artisan 命令前请参照 开发教程 → 开发使用常见问题 → 如何运行 /www/server/php/xxx/bin/php artisan xxx 命令 ① 生成数据库队列表迁移文件 在执行该步骤前&#xff0c;请先检查迁移文件 da…

【CSS 05】文本颜色 文本对齐 文字装饰 文本转换 文字间距 文本阴影 字体 字体样式 字体大小 谷歌字体

CSS 说在前面文本 text文本对齐 text-align文字装饰 text-decoration文本转换 text-transform文字间距 text_spacing文本阴影 text-shadow字体 font字体样式 font-style字体大小 font-size谷歌字体简写属性 shorthand 说在前面 事实证明&#xff0c;Zoro只要出现在标题就会被识…

go-GUI开发:fyne解决中文乱码+注册windows服务

go-GUI框架&#xff1a;fyne教程及解决中文乱码等常见bug 1 fyne教程 fyne教程地址&#xff1a; https://www.topgoer.cn/docs/goday/goday-1crdp17nj4v6phttps://pkg.go.dev/fyne.io/fyne/v2#section-readme 1.1 介绍 简单易用&#xff0c;fyne提供了简单直观的API&#xff…

iOS编译提效插件cocoapods-jxedt方案详解

1. 前言 本篇文章是cocoapods-jxedt插件实现方案的详解&#xff0c;主要从以下几个方面阐述了一下插件的实现方案和历程。 插件文件目录介绍插件的工作流程介绍插件实现过程中的问题和解决方案记录 如果你对插件的使用还不了解&#xff0c;建议先读一下cocoapods-jxedt使用介…

CVE漏洞复现-CVE-2023-32233 NetFilter权限提升

CVE-2023-32233 NetFilter权限提升 Netfilter是Linux 内核中的网络数据包处理框架&#xff08;iptables&#xff09;通过各种规则和过滤器&#xff0c;基于数据包的来源、目标地址、协议类型、端口号等信息&#xff0c;控制网络流量和数据包的转发和处理具体&#xff0c;详情请…

使用贝叶斯网络预测糖尿病:从理论到实践

2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 引言 在现实世界中&#xff0c;许多变量之间存在着复杂的概率关系&#xff0c;例如天气、交通、健康等方面的因素都会相互影响。为了更好地理解…

音频基本概念

1.音频信号 音频信号是一种连续变化的模拟信号&#xff0c;但计算机只能处理和记录二进制的数字信号&#xff0c;由自然音源得到的音频信号必须经过一定的变换&#xff0c;成为数字音频信号之后&#xff0c;才能送到计算机中作进一步的处理。 数字音频系统通过将声波的波型转换…

调用腾讯云API实现英文识别

目录 1. 作者介绍2. 腾讯云英文识别API介绍2.1 英文识别原理—OCR技术2.2 腾讯云英文识别API 3. 实验过程3.1获得API3.2申请调用接口3.3调试接口3.4实验代码3.5实验结果3.6 问题分析 4. 参考连接 1. 作者介绍 乔奕婕&#xff0c;女&#xff0c;西安工程大学电子信息学院&#…

nginx系列第六篇:结合nginx梳理linux中信号的使用

nginx中master进程来管理整个nginx工作的全过程&#xff0c;运行时其通过接收外部信号输入的方式来对内部进行相关调整。本文对照nginx来梳理一下linux中信号常用API的使用。 目录 1.函数sigaction和signal 2.关于信号集sigset_t 2.1 测试程序1 2.2 测试程序1 3.信号屏蔽…

宝塔安装ModStart常见问题

Q&#xff1a;环境提示PHP未禁用危险函数 安装系统时通常会需要解禁 system,exec,passthru,shell_exec,popen,proc_open 等危险函数。部分集成环境会提示危险函数风险&#xff0c;通常可以如下方式解决&#xff1a; 该函数在通常只是在系统 系统安装/系统升级/模块安装/模块升…

【SpinalHDL快速入门】4.3、基本类型之UInt/SInt

文章目录 1.1、描述1.2、声明1.3、运算符1.3.1、逻辑运算&#xff08;Logic&#xff09;1.3.2、算术运算&#xff08;Arithmetic&#xff09;1.3.3、比较&#xff08;Comparison&#xff09;1.3.4、类型转换&#xff08;Type Cast&#xff09;1.3.5、部分赋值/提取操作符&#…

第一章:数据库概述

第一章&#xff1a;数据库概述 1.1&#xff1a;为什么要使用数据库 持久化(persistence)&#xff1a;把数据保存到可掉电式存储设备中以供之后使用。大多数情况下&#xff0c;特别是企业级应用&#xff0c;数据持久化意味着将内存中的数据保存到硬盘上加以"固化"&a…

低代码平台简单分享

低代码平台简单分享 文章目录 低代码平台简单分享1、什么是低代码&#xff1f;什么是低代码平台&#xff1f;2、低代码平台的前世今生**一、低代码的起源**二、低代码的分类三、低代码的能力四、低代码开发的特点 3、目前主流的低代码平台有哪些&#xff1f;优缺点&#xff1f;…

常用模拟低通滤波器的设计——契比雪夫II型滤波器

常用模拟低通滤波器的设计——契比雪夫II型滤波器 切比雪夫 II 型滤波器的振幅平方函数为&#xff1a; 式中&#xff0c;为有效带通截止频率&#xff0c; 是与通带波纹有关的参量&#xff0c; 大&#xff0c;波纹大&#xff0c;&#xff1b; 为 N 阶契比雪夫多项式。 在 Matl…

几种常见数据库的表和列信息查询

文章目录 前言1. oracle数据库1.1 表信息和注释信息1.2 表的列信息 2. mysql数据库2.1 常用的几个命令2.2 使用desc查看表结构2.3 表结构信息主要存在information_schema数据库2.4 主要表是columns&#xff0c;tables&#xff0c;schemata2.4.1 schemata 数据库信息2.4.2 table…

三、opengles画三角形

第一部分Java端 1&#xff09;界面 <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.andro…