Vue(十七):利用 html2canvas、JsPDF 依赖实现打印功能

news2024/11/15 16:51:55

效果

在这里插入图片描述

主程序

<!-- 打印区域 -->
<el-container ref="PdfPage">
	<!-- 过滤打印按钮 -->
	<el-button type="primary" data-html2canvas-ignore='true' @click="printPage">打印</el-button>
	<el-main>
		<!-- 滚动区域 -->
		<el-row ref="Content" :gutter="20">
			......
		</el-row>
	</el-main>
</el-container>

<script>
import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';

export default {
	name: "Home",
	methods: {
		printPage() {
			const elRef = this.$refs['PdfPage'].$el;
			const contentRef = this.$refs['Content'].$el;
			const options = {
				// width: elRef.clientWidth,
				// height: contentRef.clientHeight + 160,
				windowHeight: contentRef.clientHeight + 160,
			}
			html2canvas(elRef, options)
				.then(canvas => {
					const [w, h] = [595.28, 841.89];
					const [cw, ch] = [canvas.width, canvas.height];
					const PDF = new JsPDF('p', 'pt', 'a4');
					const pageData = canvas.toDataURL('image/jpeg', 1.0);
					PDF.addImage(pageData, 'JPEG', 0, (h - ch / (cw / w)) / 2, w, ch / (cw / w));
					PDF.save('00.pdf');
				})
		},
	},
}
</script>

源码

<template>
	<el-container class="Home">
		<el-aside width="240px">
			<el-menu default-active="1-4-1" background-color="transparent">
				<el-submenu index="1">
					<template slot="title">
						<i class="el-icon-location"></i>
						<span>导航一</span>
					</template>
					<el-menu-item-group>
						<template slot="title">分组一</template>
						<el-menu-item index="1-1">选项1</el-menu-item>
						<el-menu-item index="1-2">选项2</el-menu-item>
					</el-menu-item-group>
					<el-menu-item-group title="分组2">
						<el-menu-item index="1-3">选项3</el-menu-item>
					</el-menu-item-group>
					<el-submenu index="1-4">
						<template slot="title">选项4</template>
						<el-menu-item index="1-4-1">选项1</el-menu-item>
					</el-submenu>
				</el-submenu>
				<el-menu-item index="2">
					<i class="el-icon-menu"></i>
					<span slot="title">导航二</span>
				</el-menu-item>
				<el-menu-item index="3">
					<i class="el-icon-document"></i>
					<span slot="title">导航三</span>
				</el-menu-item>
				<el-menu-item index="4">
					<i class="el-icon-setting"></i>
					<span slot="title">导航四</span>
				</el-menu-item>
			</el-menu>
		</el-aside>
		<el-container ref="PdfPage">
			<el-header>
				<el-row type="flex" align="middle">
					<el-col :span="20">
						<el-page-header content="详情页面" />
					</el-col>
					<el-col :span="4" align="right">
						<el-button type="primary" data-html2canvas-ignore='true' @click="printPage">打印</el-button>
					</el-col>
				</el-row>
			</el-header>
			<el-main>
				<el-row ref="Content" :gutter="20">
					<el-col :span="12">
						<v-chart class="chart" :option="option1" autoresize />
					</el-col>
					<el-col :span="12">
						<v-chart class="chart" :option="option2" autoresize />
					</el-col>
					<el-col :span="24">
						<v-chart class="chart" :option="option3" autoresize />
					</el-col>
				</el-row>
			</el-main>
			<el-footer>Hello Lee!!!</el-footer>
		</el-container>
	</el-container>
</template>

<script>
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { PieChart, LineChart, BarChart } from "echarts/charts";
import {
	TitleComponent,
	TooltipComponent,
	LegendComponent,
	ToolboxComponent,
	GridComponent,
} from "echarts/components";
import VChart, { THEME_KEY } from "vue-echarts";

import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';

export default {
	name: "Home",
	components: {
		VChart
	},
	provide: {
		[THEME_KEY]: "default"
	},
	data() {
		use([
			CanvasRenderer,
			LineChart,
			PieChart,
			BarChart,
			TitleComponent,
			TooltipComponent,
			LegendComponent,
			ToolboxComponent,
			GridComponent,
		]);
		return {
			option1: {
				title: {
					text: "Traffic Sources",
					left: "center"
				},
				tooltip: {
					trigger: "item",
					formatter: "{a} <br/>{b} : {c} ({d}%)"
				},
				legend: {
					orient: "vertical",
					left: "left",
					data: [
						"Direct",
						"Email",
						"Ad Networks",
						"Video Ads",
						"Search Engines"
					]
				},
				series: [
					{
						name: "Traffic Sources",
						type: "pie",
						radius: "55%",
						center: ["50%", "60%"],
						data: [
							{ value: 335, name: "Direct" },
							{ value: 310, name: "Email" },
							{ value: 234, name: "Ad Networks" },
							{ value: 135, name: "Video Ads" },
							{ value: 1548, name: "Search Engines" }
						],
						emphasis: {
							itemStyle: {
								shadowBlur: 10,
								shadowOffsetX: 0,
								shadowColor: "rgba(0, 0, 0, 0.5)"
							}
						}
					}
				]
			},
			option2: {
				color: ['#80FFA5', '#00DDFF', '#37A2FF', '#FF0087', '#FFBF00'],
				title: {
					text: 'Gradient Stacked Area Chart'
				},
				tooltip: {
					trigger: 'axis',
					axisPointer: {
						type: 'cross',
						label: {
							backgroundColor: '#6a7985'
						}
					}
				},
				legend: {
					bottom: '0',
					data: ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']
				},
				toolbox: {
					feature: {
						saveAsImage: {}
					}
				},
				grid: {
					left: '3%',
					right: '4%',
					bottom: '5%',
					containLabel: true
				},
				xAxis: [
					{
						type: 'category',
						boundaryGap: false,
						data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
					}
				],
				yAxis: [
					{
						type: 'value'
					}
				],
				series: [
					{
						name: 'Line 1',
						type: 'line',
						stack: 'Total',
						smooth: true,
						lineStyle: {
							width: 0
						},
						showSymbol: false,
						areaStyle: {
							opacity: 0.8,
						},
						emphasis: {
							focus: 'series'
						},
						data: [140, 232, 101, 264, 90, 340, 250]
					},
					{
						name: 'Line 2',
						type: 'line',
						stack: 'Total',
						smooth: true,
						lineStyle: {
							width: 0
						},
						showSymbol: false,
						areaStyle: {
							opacity: 0.8,
						},
						emphasis: {
							focus: 'series'
						},
						data: [120, 282, 111, 234, 220, 340, 310]
					},
					{
						name: 'Line 3',
						type: 'line',
						stack: 'Total',
						smooth: true,
						lineStyle: {
							width: 0
						},
						showSymbol: false,
						areaStyle: {
							opacity: 0.8,
						},
						emphasis: {
							focus: 'series'
						},
						data: [320, 132, 201, 334, 190, 130, 220]
					},
					{
						name: 'Line 4',
						type: 'line',
						stack: 'Total',
						smooth: true,
						lineStyle: {
							width: 0
						},
						showSymbol: false,
						areaStyle: {
							opacity: 0.8,
						},
						emphasis: {
							focus: 'series'
						},
						data: [220, 402, 231, 134, 190, 230, 120]
					},
					{
						name: 'Line 5',
						type: 'line',
						stack: 'Total',
						smooth: true,
						lineStyle: {
							width: 0
						},
						showSymbol: false,
						label: {
							show: true,
							position: 'top'
						},
						areaStyle: {
							opacity: 0.8,
						},
						emphasis: {
							focus: 'series'
						},
						data: [220, 302, 181, 234, 210, 290, 150]
					}
				]
			},
			option3: (function () {
				const builderJson = {
					all: 10887,
					charts: {
						map: 3237,
						lines: 2164,
						bar: 7561,
						line: 7778,
						pie: 7355,
						scatter: 2405,
						candlestick: 1842,
						radar: 2090,
						heatmap: 1762,
						treemap: 1593,
						graph: 2060,
						boxplot: 1537,
						parallel: 1908,
						gauge: 2107,
						funnel: 1692,
						sankey: 1568
					},
					components: {
						geo: 2788,
						title: 9575,
						legend: 9400,
						tooltip: 9466,
						grid: 9266,
						markPoint: 3419,
						markLine: 2984,
						timeline: 2739,
						dataZoom: 2744,
						visualMap: 2466,
						toolbox: 3034,
						polar: 1945
					},
					ie: 9743
				};
				const downloadJson = {
					'echarts.min.js': 17365,
					'echarts.simple.min.js': 4079,
					'echarts.common.min.js': 6929,
					'echarts.js': 14890
				};
				const themeJson = {
					'dark.js': 1594,
					'infographic.js': 925,
					'shine.js': 1608,
					'roma.js': 721,
					'macarons.js': 2179,
					'vintage.js': 1982
				};
				const waterMarkText = 'ECHARTS';
				const canvas = document.createElement('canvas');
				const ctx = canvas.getContext('2d');
				canvas.width = canvas.height = 100;
				ctx.textAlign = 'center';
				ctx.textBaseline = 'middle';
				ctx.globalAlpha = 0.08;
				ctx.font = '20px Microsoft Yahei';
				ctx.translate(50, 50);
				ctx.rotate(-Math.PI / 4);
				ctx.fillText(waterMarkText, 0, 0);
				let option = {
					backgroundColor: {
						type: 'pattern',
						image: canvas,
						repeat: 'repeat'
					},
					tooltip: {},
					title: [
						{
							text: '在线构建',
							subtext: '总计 ' + builderJson.all,
							left: '25%',
							textAlign: 'center'
						},
						{
							text: '各版本下载',
							subtext:
								'总计 ' +
								Object.keys(downloadJson).reduce(function (all, key) {
									return all + downloadJson[key];
								}, 0),
							left: '75%',
							textAlign: 'center'
						},
						{
							text: '主题下载',
							subtext:
								'总计 ' +
								Object.keys(themeJson).reduce(function (all, key) {
									return all + themeJson[key];
								}, 0),
							left: '75%',
							top: '50%',
							textAlign: 'center'
						}
					],
					grid: [
						{
							top: 50,
							width: '50%',
							bottom: '45%',
							left: 10,
							containLabel: true
						},
						{
							top: '55%',
							width: '50%',
							bottom: 0,
							left: 10,
							containLabel: true
						}
					],
					xAxis: [
						{
							type: 'value',
							max: builderJson.all,
							splitLine: {
								show: false
							}
						},
						{
							type: 'value',
							max: builderJson.all,
							gridIndex: 1,
							splitLine: {
								show: false
							}
						}
					],
					yAxis: [
						{
							type: 'category',
							data: Object.keys(builderJson.charts),
							axisLabel: {
								interval: 0,
								rotate: 30
							},
							splitLine: {
								show: false
							}
						},
						{
							gridIndex: 1,
							type: 'category',
							data: Object.keys(builderJson.components),
							axisLabel: {
								interval: 0,
								rotate: 30
							},
							splitLine: {
								show: false
							}
						}
					],
					series: [
						{
							type: 'bar',
							stack: 'chart',
							z: 3,
							label: {
								position: 'right',
								show: true
							},
							data: Object.keys(builderJson.charts).map(function (key) {
								return builderJson.charts[key];
							})
						},
						{
							type: 'bar',
							stack: 'chart',
							silent: true,
							itemStyle: {
								color: '#eee'
							},
							data: Object.keys(builderJson.charts).map(function (key) {
								return builderJson.all - builderJson.charts[key];
							})
						},
						{
							type: 'bar',
							stack: 'component',
							xAxisIndex: 1,
							yAxisIndex: 1,
							z: 3,
							label: {
								position: 'right',
								show: true
							},
							data: Object.keys(builderJson.components).map(function (key) {
								return builderJson.components[key];
							})
						},
						{
							type: 'bar',
							stack: 'component',
							silent: true,
							xAxisIndex: 1,
							yAxisIndex: 1,
							itemStyle: {
								color: '#eee'
							},
							data: Object.keys(builderJson.components).map(function (key) {
								return builderJson.all - builderJson.components[key];
							})
						},
						{
							type: 'pie',
							radius: [0, '30%'],
							center: ['75%', '25%'],
							data: Object.keys(downloadJson).map(function (key) {
								return {
									name: key.replace('.js', ''),
									value: downloadJson[key]
								};
							})
						},
						{
							type: 'pie',
							radius: [0, '30%'],
							center: ['75%', '75%'],
							data: Object.keys(themeJson).map(function (key) {
								return {
									name: key.replace('.js', ''),
									value: themeJson[key]
								};
							})
						}
					]
				};
				return option;
			})(),
		}
	},
	methods: {
		printPage() {
			const elRef = this.$refs['PdfPage'].$el;
			const contentRef = this.$refs['Content'].$el;
			const options = {
				// width: elRef.clientWidth,
				// height: contentRef.clientHeight + 160,
				windowHeight: contentRef.clientHeight + 160,
			}
			html2canvas(elRef, options)
				.then(canvas => {
					const [w, h] = [595.28, 841.89];
					const [cw, ch] = [canvas.width, canvas.height];
					const PDF = new JsPDF('p', 'pt', 'a4');
					const pageData = canvas.toDataURL('image/jpeg', 1.0);
					PDF.addImage(pageData, 'JPEG', 0, (h - ch / (cw / w)) / 2, w, ch / (cw / w));
					PDF.save('00.pdf');
				})
		},
	},
}
</script>

<style lang="less" scoped>
.Home {
	position: relative;
	width: 100%;
	height: 100%;

	.el-header {
		background-color: #B3C0D1;

		.el-row {
			height: 100%;
		}
	}

	.el-footer {
		background-color: #B3C0D1;
		line-height: 60px;
	}

	.el-aside {
		background-color: #D3DCE6;
	}

	.el-main {
		background-color: #E9EEF3;
	}

	.chart {
		height: 500px;
	}
}
</style>

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

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

相关文章

AI绘画——Three Delicacy Wonton (三餡馄饨Mix)模型

目录 怎么做三鲜馄饨Mix&#xff1a; 描述&#xff1a; 版本&#xff1a; 使用说明&#xff1a; 实操演示&#xff08;多图预警&#xff09; Picture One Picture Two Picture Three 怎么做三鲜馄饨Mix&#xff1a; 切一点金弘道 &#xff08;https://civitai.com/mo…

无人机遥感影像应用

目录 一、无人机遥感技术 二、无人机遥感影像数据生产 三、无人机遥感影像应用 一、无人机遥感技术 1.无人机遥感系统组成 1.1无人机遥感系统组成—无人机平台 1.2无人机遥感系统组成—传感器 2.无人机遥感技术的特点 高时效性&#xff1a;准确并快速获取地表数据 高分辨率…

加密算法在链接防抓取和数据防篡改应用

写在前 对工作中遇到的加密算法算法进行总结和思考&#xff0c;分析不同加密算法优缺点和对应解决问题场景&#xff0c;思考进一步可改进点。 场景1、加密算法在链接防止抓取中应用 客户端和服务器端对(appverisionurl盐offset)使用加密规则进行加密&#xff0c;对传输数据进…

bing搜索技巧

“” 双引号表示完全匹配&#xff0c;结果中必须出现与搜索文本完全相同的内容。 2 A -B 搜索包含A但不包含B的结果&#xff08;请注意A后面的空格不能省略&#xff09; 3 filetype 搜索对应类型的文件。例如&#xff1a;中国防火墙 filetype:ppt&#xff0c;即为搜索包含主题…

Hive概论、架构和基本操作

Hive是一个构建在Hadoop上的数据仓库框架&#xff0c;最初&#xff0c;Hive是由Facebook开发&#xff0c;后台移交由Apache软件基金会开发&#xff0c;并做为一个Apache开源项目。 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&a…

【Maven 入门】第三章、Maven POM

一、什么是 Maven POM&#xff1f; POM 是 Maven 中最重要的概念之一&#xff0c;它描述了一个 Maven 项目的基本信息和依赖关系。简单来说&#xff0c;POM 就是一个 XML 文件&#xff0c;其中包含了以下内容&#xff1a; 项目的基本信息&#xff0c;如名称、版本号、描述等。…

超详细Redis入门教程——Redis 的安装与配置

前言 本文小新为大家带来 超详细Redis入门教程——Redis 的安装与配置 相关知识&#xff0c;具体内容包括Redis 的安装&#xff0c;连接前的配置&#xff0c;Redis 客户端分类&#xff08;包括&#xff1a;命令行客户端&#xff0c;图形界面客户端&#xff0c;Java 代码客户端&…

政策和技术引导企业布局光伏组件回收市场 积极应对光伏组件“退役潮”

一、发展光伏组件回收是实现我国碳中和的战略需求 光伏组件回收主要是通过对其各组件部分进行物理或化学方法处理&#xff0c;进而得到拥有经济价值的材料&#xff0c;进而减少环境污染&#xff0c;实现对废弃光伏组件资源的回收再利用。 我国是光伏组件制造及应用大国&#…

远程仓库的克隆和上传

要创建项目文件夹下打开Git Bush Here --> git clone 远程仓库地址 ! 没有权限访问 原因: 之前登过别人邮箱号,导致克隆失败 解决: 第一步. C盘->用户->电脑用户名->.gitconfig->用vscode打开删除信息,然后保存即可 . 第二步.电脑搜索找到 凭据管理器->wi…

【Python_Scrapy学习笔记(十一)】基于Scrapy框架的下载器中间件添加Cookie参数

基于Scrapy框架的下载器中间件添加Cookie参数 前言 本文中介绍 如何基于 Scrapy 框架的下载器中间件添加 Cookie 参数。 正文 1、添加中间件的流程 在 middlewares.py 中新建 Cookie参数 中间件类在 settings.py 中添加此下载器中间件&#xff0c;设置优先级并开启 2、基…

【C++初阶】命名空间 namespace

一.前言 在正式进入C前&#xff0c;我们需要先了解了解C。顾名思义&#xff0c;C是基于C的一种编程语言&#xff0c;相较于C&#xff0c;C写出来的代码更简洁&#xff0c;有时候C需要几百行代码&#xff0c;而C只需要几十行就可以解决&#xff0c;C也很好的解决了C中存在的一些…

【夜莺监控搭建】

夜莺监控搭建V6版本 v6版本系统架构安装部署安装时序数据库安装mysql、redis和n9e&#xff08;夜莺主程序&#xff09;安装categraf 登录平台如何修改密码添加数据源 官网&#xff1a; https://flashcat.cloud/ GitHub项目地址&#xff1a; https://github.com/ccfos/nightin…

Mongo集群化部署+高可用架构

数据库开发系列 文章目录 数据库开发系列前言一、MongoDB存储引擎二、MongoDB 复制&#xff08;副本集&#xff09;三、为什么需要分片集群架构四、高可用分片集群架构&#xff08;复制集&#xff09;总结 前言 数据库的演进 随着计算机的发展&#xff0c;越来越多的数据需要被…

python+vue 服装穿搭信息管理系统

本系统采用自上往下的方法开发&#xff0c;基本定位如下功能&#xff1a; 本课题要求实现一套服装信息管理系统的设计与实现&#xff0c;系统主要包括管理员模块和用户模块功能模块。 由于本系统需要在不同设备上都能运行&#xff0c;而且电脑配置要求也要越低越好&#xff0c…

SpringMVC框架详解(学习总结)

目录 什么是MVC SpringMVC概述 SpringMVC常见开发方式 SpringMVC执行流程 SpringMVC核心组件介绍 快速构建Spring MVC程序 SpringMVC参数绑定 SpringMVC跳转方式 SpringMVC处理json请求和响应 SpringMVC静态资源处理 SpringMVC操作session和cookie SpringMVC拦截器 …

基于nuxt3的语雀文档批量导出

语雀文档批量导出 快速访问 Github Blog 项目由来 语雀是一个不错的笔记与文档知识库&#xff0c;但是最近发现他开始割韭菜了&#xff0c; 知识库的公开开始收费&#xff0c;就想着把内容都导出自己来部署&#xff0c;发现并没有批量操作&#xff0c;amazing&#xff0c;…

美国运营商PTCRB认证PTCRB认证怎么做PTCRB认证是什么?

大家好&#xff0c;今天我想和大家分享一下什么是PTCRB认证&#xff01; PTCRB是指个人通信服务型号认证评估委员会&#xff0c;由北美移动运营商于1997年成立。目前的运营商已经不仅限于北美&#xff0c;而是涵括全球范围内的移动运营商成员。其目的是为包括Cellular GERAN&a…

Session使用和原理分析图与实现原理-- 代码演示说明 Session 的生命周期和读取的机制代码分析

目录 Web 开发会话技术 -Session —session 技术 session 基本原理 Session 可以做什么 如何理解 Session Session 的基本使用 session 底层实现机制 原理分析图 代码演示 CreateSession.java 测试 Session 创的机制&#xff0c; 注意抓包分析​编辑 ReadSession.j…

C盘文件删除怎么做?3个方法教你清理C盘!

案例&#xff1a;C盘文件怎么删除&#xff1f; 【我的电脑使用了一年多了&#xff0c;现在C盘已经快满了&#xff0c;想知道C盘里的文件哪些可以进行删除&#xff1f;感谢&#xff01;】 C盘是计算机系统盘&#xff0c;存储了操作系统和应用程序等重要文件&#xff0c;因此&a…

机器视觉助力锂电行业升级转型—章鱼博士视控一体化解决方案

摘要&#xff1a; 机器视觉在工业领域中充当了模拟人眼的作用&#xff0c;通过其高效的感知能力、精确的检测准确性、可定制性和较低的人工成本等特点&#xff0c;已逐渐成为工业智能化转型的核心功能。在锂电池领域&#xff0c;机器视觉扮演着许多重要的角色&#xff0c;包括生…