前端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…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
