前端Vue框架实现html页面输出pdf(html2canvas,jspdf)
代码demo:
<template><el-dialog class="storageExportDialog" :fullscreen="true" title="" :visible.sync="visible" v-if="visible" width="600px"><div id="exportContainer" class="exportContainer"><div id="exportContent0" class="exportContent" ref="exportContent0"><div class="header"><div class="left">{{ `Order: ${orderNmae}` }}</div><div class="right">{{ `1/${dataSlices.length+1}` }}</div></div><div class="data1"><el-row><el-col :span="4" class="label">Wire End ID :</el-col><el-col :span="4" class="value">1</el-col><el-col :span="4" class="label">Wire ID :</el-col><el-col :span="4" class="value">2</el-col><el-col :span="4" class="label">Operator :</el-col><el-col :span="4" class="value">3</el-col></el-row><el-row><el-col :span="4" class="label">Wire End Description :</el-col><el-col :span="4" class="value">4</el-col><el-col :span="4" class="label">Wire Description :</el-col><el-col :span="4" class="value">5</el-col><el-col :span="4" class="label">Good :</el-col><el-col :span="4" class="value">6</el-col></el-row><el-row><el-col :span="4" class="label">Terminal ID :</el-col><el-col :span="4" class="value">7</el-col><el-col :span="4" class="label">Seal ID :</el-col><el-col :span="4" class="value">8</el-col><el-col :span="4" class="label">Bad :</el-col><el-col :span="4" class="value">9</el-col></el-row><el-row><el-col :span="4" class="label">Terminal Description : </el-col><el-col :span="4" class="value">10</el-col><el-col :span="4" class="label">Seal Description :</el-col><el-col :span="4" class="value">11</el-col><el-col :span="4" class="label">Total :</el-col><el-col :span="4" class="value">12</el-col></el-row></div><div class="data2"><el-row><el-col :span="6" class="title">Tolerance</el-col></el-row><el-row><el-col :span="3" class="label">ATOL+: </el-col><el-col :span="3" class="value">5.0 %</el-col><el-col :span="3" class="label">STOL+: </el-col><el-col :span="3" class="value">10 %</el-col><el-col :span="3" class="label">ZONE 1:</el-col><el-col :span="3" class="value">20 pts</el-col><el-col :span="3" class="label">Z1TOL+:</el-col><el-col :span="3" class="value">25 %</el-col></el-row><el-row><el-col :span="3" class="label">ATOL-: </el-col><el-col :span="3" class="value">3.0 %</el-col><el-col :span="3" class="label">STOL-: </el-col><el-col :span="3" class="value">4 %</el-col><el-col :span="3" class="label">Filter: </el-col><el-col :span="3" class="value">35 %</el-col><el-col :span="3" class="label">Z1TOL-:</el-col><el-col :span="3" class="value">90 %</el-col></el-row></div><div class="data3"><el-row><el-col :span="6" class="title">Tolerance</el-col></el-row><el-row><el-col :span="4" class="label">Crimp Height:</el-col><el-col :span="20" class="value">0.000 mm (+0.000 mm/-0.000 mm)</el-col></el-row><el-row><el-col :span="4" class="label">Crimp Height:</el-col><el-col :span="20" class="value">0.000 mm (+0.000 mm/-0.000 mm)</el-col></el-row><el-row><el-col :span="4" class="label">Min Pull Force:</el-col><el-col :span="20" class="value">0.0 N</el-col></el-row></div><div class="data4"><el-row><el-col :span="6" class="title">Quality Verification</el-col><el-col :span="6">(Samples: 0)</el-col></el-row><el-row><el-col :span="1" class="label"></el-col><el-col :span="3" class="label">Crimp Height</el-col><el-col :span="3" class="label">Crimp Width</el-col><el-col :span="3" class="label">Pull Force</el-col></el-row></div><div class="data5"><div class="chart1" ref="chart1"></div><div class="chart2" ref="chart2"></div></div><div class="data6"><div class="chart3" ref="chart3"></div></div><div class="data7"><div class="chart4" ref="chart4"></div></div></div><div v-for="(slice, index) in dataSlices" :key="index" :id="`exportContent${index+1}`" class="exportContent" :ref="`exportContent${index+1}`"><div class="header"><div class="left">{{ `Order: ${orderNmae}` }}</div><div class="right">{{ `${index+2}/${dataSlices.length+1}` }}</div></div><el-table class="dataTable" ref="dataTable" :data="slice" style="width: 100%;" stripe><el-table-column align="center" prop="index" label="No."></el-table-column><el-table-column align="center" prop="x" label="X Val"></el-table-column><el-table-column align="center" prop="date" label="Date"></el-table-column><el-table-column align="center" prop="time" label="Time"></el-table-column></el-table></div></div><div slot="footer" class="dialog-footer"><el-button type="success" @click="exportFn" icon="el-icon-printer" plain>导出</el-button><el-button type="danger" @click="visible = false" icon="el-icon-close" plain>关闭</el-button></div></el-dialog>
</template><script>
import { getCurrentDateTime } from "@/utils/common.js"
import * as echarts from "echarts";
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
export default {name: 'storageExport',data() {return {orderNmae: "test",chunkSize: 44, // 表格每页行数loading: null,chart1: null,chart2: null,chart3: null,chart4: null,visible: false,printTableData: [],}},watch: {visible() {if (this.visible == true) {this.initDataChart();} else {this.chart.dispose();this.chart = null;}}},computed: {dataSlices() {const slices = [];for (let i = 0; i < this.printTableData.length; i += this.chunkSize) {slices.push(this.printTableData.slice(i, i + this.chunkSize));}return slices;}},mounted() {for (let i = 1; i <= 100; i++) {this.printTableData.push({ index: i, date: "2024-09-09", time: "15:13:15", x: "1.5" },)}},beforeDestroy() {},methods: {initDataChart() {this.$nextTick(() => {this.chart1 = echarts.init(this.$refs['chart1']);this.chart2 = echarts.init(this.$refs['chart2']);this.chart3 = echarts.init(this.$refs['chart3']);this.chart4 = echarts.init(this.$refs['chart4']);let option = {grid: {left: '10%',right: '10%',bottom: '10%',top: '10%',containLabel: true},xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']},yAxis: {type: 'value'},series: [{data: [820, 932, 901, 934, 1290, 1330, 1320],type: 'line',smooth: true}]};this.chart1.setOption(option);this.chart2.setOption(option);this.chart3.setOption(option);this.chart4.setOption(option);})},exportFn() {this.showLoading();console.log("导出");try {const pdf = new jsPDF('p', 'mm', 'a4');let imgs = [];let list = document.querySelectorAll('.exportContent');let addPromises = [];for (let i = 0; i < list.length; i++) {let img = list[i];let addPromise = new Promise((resolve, reject) => {html2canvas(img, { scale: 2 }).then((canvas) => {imgs.push(canvas)resolve();})});addPromises.push(addPromise);}Promise.all(addPromises).then(() => {console.log("imgs", imgs);imgs.forEach((img, index) => {const imgData = img.toDataURL('image/webp');pdf.addImage(imgData, 'WEBP', 0, 0, 210, 297);if (index < imgs.length - 1) {pdf.addPage();}})this.savePdfFile(pdf);}).finally(() => {this.closeLoading();})} catch (e) {console.log("导出失败", e);this.closeLoading();}},showLoading() {this.loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.5)'});},closeLoading() {this.loading.close();},savePdfFile(pdf) {const pdfBlob = pdf.output('blob');const pdfUrl = URL.createObjectURL(pdfBlob);const fileName = `${getCurrentDateTime()}.pdf`; // 自定义文件名const link = document.createElement('a');link.href = pdfUrl;link.download = fileName;document.body.appendChild(link);link.click();document.body.removeChild(link);let timer = setTimeout(() => {URL.revokeObjectURL(pdfUrl);clearTimeout(timer);}, 1000 * 10); // 10s 后释放 URL}}
}
</script><style lang="scss" scoped>
::v-deep.storageExportDialog {.el-dialog__footer {position: fixed;top: 0;right: 0;padding: 5px;}
}
::v-deep.exportContainer {display: flex;flex-direction: column;justify-content: center;align-items: center;.exportContent {width: 210mm;height: 297mm;border: 0.1px solid #ccc;overflow: scroll;.header {width: 100%;height: 10mm;display: flex;justify-content: space-between;align-items: center;border: 0.1px solid #ccc;.left {padding: 1mm;font-size: 18px;font-weight: bold;}.right {padding: 1mm;font-size: 12px;}}.data1 {width: 100%;height: 30mm;border: 0.1px solid #ccc;font-size: 12px;font-weight: bolder;.label {height: 7.5mm;line-height: 7.5mm;text-align: right;}.value {height: 7.5mm;line-height: 7.5mm;padding-left: 2mm;text-align: left;}}.data2 {width: 100%;height: 20mm;font-size: 12px;.title {height: 5mm;padding-left: 3mm;line-height: 5mm;font-weight: bolder;}.label {height: 7.5mm;line-height: 7.5mm;text-align: right;}.value {height: 7.5mm;line-height: 7.5mm;padding-left: 2mm;text-align: left;}}.data3 {width: 100%;height: 25mm;font-size: 12px;.title {height: 4mm;padding-left: 3mm;line-height: 4mm;font-weight: bolder;}.label {height: 7mm;line-height: 7mm;text-align: right;}.value {height: 7mm;line-height: 7mm;padding-left: 2mm;text-align: left;}}.data4 {width: 100%;height: 10mm;font-size: 12px;.title {height: 4mm;padding-left: 3mm;line-height: 4mm;font-weight: bolder;}.label {height: 6mm;line-height: 6mm;text-align: center;}}.data5 {height: 65mm;width: 100%;display: flex;border-bottom: 0.1px solid #ccc;.chart1,.chart2 {height: 65mm;width: 50%;}}.data6 {height: 65mm;width: 100%;.chart3 {height: 65mm;width: 100%;}}.data7 {height: 65mm;width: 100%;.chart4 {height: 65mm;width: 100%;}}.dataTable {.el-table__cell {padding: 0;font-size: 12px;}}}
}
</style>
页面效果:

导出效果:

相关文章:
前端Vue框架实现html页面输出pdf(html2canvas,jspdf)
代码demo: <template><el-dialog class"storageExportDialog" :fullscreen"true" title"" :visible.sync"visible" v-if"visible" width"600px"><div id"exportContainer" …...
SAP Fiori UI5-环境搭建-2022-2024界面对比
文章目录 一、Fiori项目初始化实际操作第一步:新建文件夹(项目文件)第二步:打开我们项目第三步:打开终端 部署环境第四步: XML中新增文本 二、 2023年Vscode中Fiori界面三 、2024年Vscode中Fiori界面 一、Fiori项目初始…...
二百六十三、Java——IDEA项目打成jar包,然后在Linux中运行
一、目的 在用Java对原Kafka的JSON字段解析成一条条数据,然后写入另一个Kafka中,代码写完后打成jar包,放在Linux中,直接用海豚调度运行 二、Java利用fastjson解析复杂嵌套json字符串 这一块主要是参考了这个文档,然…...
【OpenCV2.2】图像的算术与位运算(图像的加法运算、图像的减法运算、图像的融合)、OpenCV的位运算(非操作、与运算、或和异或)
1 图像的算术运算 1.1 图像的加法运算 1.2 图像的减法运算 1.3 图像的融合 2 OpenCV的位运算 2.1 非操作 2.2 与运算 2.3 或和异或 1 图像的算术运算 1.1 图像的加法运算 add opencv使用add来执行图像的加法运算 图片就是矩阵, 图片的加法运算就是矩阵的加法运算, 这就要求加…...
ChatGPT 3.5/4.0使用手册:解锁人工智能的无限潜能
1. 引言 在人工智能的浪潮中,ChatGPT以其卓越的语言理解和生成能力,成为了一个革命性的工具。它不仅仅是一个聊天机器人,更是一个能够协助我们日常工作、学习和创造的智能伙伴。随着ChatGPT 3.5和4.0版本的推出,其功能和应用范围…...
E32.【C语言 】练习:蓝桥杯题 懒羊羊字符串
1.题目 【问题描述】 “懒羊羊”字符串是一种特定类型的字符串,它由三个字符组成,具有以下特点: 1.字符串长度为 3. 2.包含两种不同的字母。 3.第二个字符和第三个字符相同 换句话说,“懒羊羊”字符串的形式应为 ABB,其中A和B是不…...
Linux 网络基础概念
文章目录 一、初始协议1、理解2、协议分层3、软件分层4、OSI七层模型5、TCP/IP五层模型 二、再识协议1、为什么要有TCP/IP协议2、什么是TCP/IP协议3、TCP/IP协议与操作系统的关系(宏观上,怎么实现的) 三、网络传输基本流程1、mac地址2、TCP/I…...
【题目】MySQL选择题
来源:MySQL专项练习选择题 1.有一个User用户表,要删除整张表(指完全删除表数据和结构),下面正确的MySQL语句是: A.DELETE TABLE User; B.DROP TABLE User; C.TRUNCATE TABLE User; D.DELETE FROM User …...
自然语言处理系列六十三》神经网络算法》LSTM长短期记忆神经网络算法
注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 自然语言处理系列六十三神经网络算法》LSTM长短期记忆神经网络算…...
亚马逊IP关联及其解决方案
在电子商务领域,亚马逊作为全球领先的在线购物平台,吸引了众多商家和个人的参与。然而,随着业务规模的扩大,商家在使用亚马逊服务时可能会遇到IP关联的问题,这不仅影响账户的正常运营,还可能带来一系列不利…...
Definition and Detection of Defects in NFT Smart Contracts论文解读、复现
背景知识\定义 NFT 是数字或物理资产所有权的区块链表示。不仅限于数字图片,视频和画作等艺术品也可以转化为 NFT 进行交易。近年来受到广泛关注,2021 年 NFT 交易额达到约 410 亿美元。 智能合约 是在区块链上运行的图灵完备程序。支持各种去中心化…...
Neo4j图数据库
文章目录 一、Neo4J相关介绍1.为什么需要图数据库方案1:Google方案2:Facebook 2.特定和优势3.什么是Neo4j4.Neo4j数据模型图论基础属性图模型Neo4j的构建元素 5.软件安装 二、CQL语句1.CQL简介2.CREATE 命令3.MATCH 命令4.RETURN 子句5.MATCH和RETURN6.C…...
k8s API资源对象
API资源对象Deployment 最小的资源是pod,deployment是多个pod的集合(多个副本实现高可用、负载均衡等)。 使用yaml文件来配置、部署资源对象。 Deployment YAML示例: vi ng-deploy.yaml apiVersion: apps/v1 kind: Deployment…...
GB/T28181规范解读之编码规则详解
GB/T28181,即《安全防范视频监控联网系统信息传输、交换、控制技术要求》,是我国安防行业的重要标准之一。该标准详细规定了城市监控报警联网系统中信息传输、交换、控制的互联结构、通信协议结构,以及传输、交换、控制的基本要求和安全性要求…...
Vue封装的过度与动画(transition-group、animate.css)
目录 1. Vue封装的过度与动画1.1 动画效果11.2 动态效果21.3 使用第三方动画库animate.css 1. Vue封装的过度与动画 作用:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名 1.1 动画效果1 Test1.vue: transition内部只能包含一个子标签。…...
免费云服务器申请教程
免费云服务器的申请流程通常包括以下几个步骤,但请注意,不同云服务提供商的具体步骤可能略有不同。以下是一个通用的申请流程: 一、选择合适的云服务提供商 首先,需要选择一家提供免费云服务器服务的云服务提供商。 免费云服务器汇…...
Spring Cloud Gateway中的常见配置
问题 最近用到了Spring Cloud Gateway,这里记录一下这个服务的常见配置。 spring:data:redis:host: ${REDIS_HOST:xxx.xxx.xxx.xxx}port: ${REDIS_PORT:2345wsd}password: ${REDIS_PASS:sdfsdfgh}database: ${REDIS_DB:8}session:redis:flush-mode: on_savenamespa…...
SelectDB 多计算集群核心设计要点揭秘与场景应用
需求起源 SelectDB 设计多计算集群架构初衷主要源于两类典型的使用场景: 写入与读取隔离:传统数仓架构中,数据的写入和读取在同一个计算集群,当遇到业务写入高峰期或突增的写入压力时,容易因资源相互抢占影响查询服务…...
Docker 清理和查看镜像与容器占用情况
查看容器占用磁盘大小 docker system df 查看单个image、container大小: docker system df -v 清理所有废弃镜像与Build Cache docker system prune -a...
如何在Android 12 aosp系统源码中添加三指下滑截图功能
如何在Android 12 aosp系统源码中添加三指下滑截图功能 系统中截图api非常简单: private static ScreenshotHelper sScreenshotHelper;sScreenshotHelper new ScreenshotHelper(mContext);//调用 sScreenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHO…...
从学术研究到工业部署,Python张量框架选型决策树(含模型规模×硬件约束×团队能力×合规要求4维评估矩阵)
第一章:从学术研究到工业部署,Python张量框架选型决策树(含模型规模硬件约束团队能力合规要求4维评估矩阵)在将深度学习模型从论文实验推向生产环境的过程中,张量框架的选择远不止“谁更流行”的简单判断。它是一次多目…...
乳腺癌治疗新思路:除了ER/PR/HER2,你的单细胞数据里还藏着哪些靶点?(附PLK1抑制剂案例)
乳腺癌精准治疗新靶点:单细胞数据驱动的PLK1抑制剂开发路径 当临床医生面对三阴性乳腺癌患者时,传统分子分型往往无法提供足够的治疗指引。最新单细胞测序技术揭示,在ER/PR/HER2这些经典标志物之外,肿瘤微环境中还隐藏着更具临床价…...
TargetMol明星分子—— Eragidomide Mezigdomide
Eragidomide ,别名 CC-90009、 Cereblon modulator 1,是一种 GSPT1 选择性 cereblon (CRBN) E3 泛素连接酶调节剂,以分子胶的方式作用。它通过 CRL4CRBN 选择性靶向 GSPT1 进行泛素化和蛋白酶体降解。 Mezigdomide 货号 T10703,别…...
VMware安装RHEL9连接Xshell与Linux基础命令vim练习
1、在VMware上创建虚拟机以及安装RHEL9操作系统,使用ssh进行远程连接2、文件管理命令练习: 1(1)在/opt目录下创建一个临时目录tmp;2(2)在临时目录下创建一个文件,文件名为a.txt;3、vi/vim练习:完成如下步骤(1)应用vi命令在/tmp文件夹下创建文…...
WarcraftHelper全方位优化指南:解决魔兽争霸III现代适配难题
WarcraftHelper全方位优化指南:解决魔兽争霸III现代适配难题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 当你在4K显示器上启动魔兽争霸…...
Ubuntu 20.04安装MATLAB R2023B保姆级避坑指南:从卸载旧版到选对产品,一步一截图
Ubuntu 20.04安装MATLAB R2023B全流程实战:从彻底卸载到精准选配 在科研与工程计算领域,MATLAB始终保持着不可替代的地位。当最新版的R2023B遇上Ubuntu 20.04这个长期支持版本,如何实现完美部署却让不少用户望而却步。不同于Windows下的图形化…...
保姆级教程:Windows下GDC-client下载TCGA数据的完整配置流程(含环境变量与配置文件修改)
Windows平台TCGA数据下载全流程:从环境配置到实战避坑指南 在生物信息学研究中,TCGA数据库无疑是癌症基因组学的宝库。但对于刚入门的研究者来说,获取这些数据往往成为第一道门槛。本文将彻底解决Windows用户在使用GDC-client工具时的各种&qu…...
XUnity.AutoTranslator IL2CPP兼容性深度解析:从诊断到根治的终极指南
XUnity.AutoTranslator IL2CPP兼容性深度解析:从诊断到根治的终极指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏自动翻译的标杆工具,在5…...
VMware虚拟机部署Mirage Flow:多环境测试方案
VMware虚拟机部署Mirage Flow:多环境测试方案 为开发测试构建安全可靠的隔离环境 1. 环境准备与虚拟机配置 在开始部署Mirage Flow之前,我们需要先准备好合适的测试环境。使用VMware虚拟机是个不错的选择,它能为我们提供一个完全隔离的测试空…...
Nunchaku FLUX.1-dev效果实测:低光照/夜景/逆光等复杂场景表现
Nunchaku FLUX.1-dev效果实测:低光照/夜景/逆光等复杂场景表现 你是不是也遇到过这样的烦恼?想用AI生成一张夜景照片,结果画面一片死黑,细节全无;或者想创作一张逆光人像,结果人物脸部黑成一团,…...
