导出为PDF加封面且分页处理dom元素分割
文章目录
- 正常展示页面
- 导出后效果
- 代码
正常展示页面
导出后效果
代码
组件内
<template><div><div><div class="content" id="content" style="padding: 0px 20px"><div class="item"><divstyle="height: 200px; width: 100%; background: pink; display: none"ref="wrap"><h1>封面</h1></div></div><!-- 每一块dom的class类设置成item(自定义)以此处理内容分割 --><div class="item"><button @click="outPutPdfFn">导出</button><!-- 组件 可为任意内容 --><el-row><el-col :span="12"><Echrats indData_id="echarts" /></el-col><el-col :span="12"><Echrats indData_id="echarts1" /></el-col></el-row></div><div class="item">内容22<!-- 组件 可为任意内容 --><el-row><el-col :span="12"><Table /></el-col><el-col :span="12"><Table /></el-col></el-row></div><div class="item">内容22 <el-row><el-col :span="12"><Table /></el-col><el-col :span="12"><Table /></el-col></el-row><Echrats indData_id="echarts3" /></div><div class="item" style="padding: 20px 0">gsd<!-- 组件 可为任意内容 --><Echrats indData_id="echarts2" /></div><div class="item" style="padding: 20px 0">内容22<!-- 组件 可为任意内容 --><Table style="margin-top: 40px" /></div><div class="item">gsd<!-- 组件 可为任意内容 --><Table style="margin-top: 40px" /><Echrats indData_id="echarts4" /></div></div></div></div>
</template><script>
import Echrats from "./new_content/components/echarts.vue";
import Table from "./new_content/components/table.vue";
import getPdf from "@/utils/pdf";
export default {components: {Echrats,Table,},methods:{outPutPdfFn() {let vm = this;const A4_WIDTH = 592.28;const A4_HEIGHT = 841.89;// $myLoading 自定义等待动画组件,实现导出事件的异步等待交互// this.$myLoading('正在导出pdf,请稍候。。。', true);vm.$nextTick(() => {// dom的id。this.$refs.wrap.style.display = "block";let target = document.getElementById("content");let pageHeight = (target.scrollWidth / A4_WIDTH) * A4_HEIGHT;// 获取分割dom,此处为class类名为item的domlet lableListID = document.getElementsByClassName("item");// 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割for (let i = 0; i < lableListID.length; i++) {let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) /pageHeight);if (this.isSplit(lableListID, i, multiple * pageHeight)||i===0) {let divParent = lableListID[i].parentNode; // 获取该div的父节点let newNode = document.createElement("div");newNode.className = "emptyDiv";newNode.style.background = "#ffffff";let _H =multiple * pageHeight -(lableListID[i].offsetTop + lableListID[i].offsetHeight);newNode.style.height = _H + 30 + "px";newNode.style.width = "100%";let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点// 判断兄弟节点是否存在console.log(next);if (next) {// 存在则将新节点插入到div的下一个兄弟节点之前,即div之后divParent.insertBefore(newNode, next);} else {// 不存在则直接添加到最后,appendChild默认添加到divParent的最后divParent.appendChild(newNode);}}}// 传入title和dom标签,此处是 #content// 异步函数,导出成功后处理交互getPdf("巡检报告单-" + "000" + "-" + "嘿嘿嘿", "#content").then(() => {// 自定义等待动画关闭// this.$myLoading(false);this.$message({type: "success",message: "导出成功",});}).catch(() => {// this.$myLoading(false);this.$message({type: "error",message: "导出失败,请重试",});});this.$refs.wrap.style.display = "none";const arr = document.getElementsByClassName("emptyDiv");const l = arr.length;for (let i = l - 1; i >= 0; i--) {if (arr?.[i] != null) {arr?.[i]?.remove(arr[i]);}}});},isSplit(nodes, index, pageHeight) {// 计算当前这块dom是否跨越了a4大小,以此分割if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight &&nodes[index + 1] &&nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {return true;}return false;},}
};
</script><style lang="scss" scoped>.item{
margin-top: 30px;
}
</style>>
jsPdf.js
// 导出页面为PDF格式
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';const getPdf = function (title, dom) {// 注册getPdf方法,传入两个参数,此处使用了promise处理导出后的操作/*title: 导出文件名dom: 需要导出dom的id*/return new Promise((resolve, reject) => {html2Canvas(document.querySelector(dom), {useCORS: true, // 由于打印时,会访问dom上的一些图片等资源,解决跨域问题!!重要allowTaint: true // 允许跨域}).then(function (canvas) {let contentWidth = canvas.width;let contentHeight = canvas.height;// 根据A4纸的大小,计算出dom相应比例的尺寸let pageHeight = contentWidth / 592.28 * 841.89;let leftHeight = contentHeight;let position = 0;let imgWidth = 595.28;// 根据a4比例计算出需要分割的实际dom位置let imgHeight = 592.28 / contentWidth * contentHeight;// canvas绘图生成image数据,1.0是质量参数let pageData = canvas.toDataURL('image/jpeg', 1.0);// a4大小let PDF = new JsPDF('', 'pt', 'a4');// 当内容达到a4纸的高度时,分割,将一整块画幅分割出一页页的a4大小,导出pdfif (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();}}}// 导出PDF.save(title + '.pdf');resolve(true);}).catch(() => {reject(false);});});
};
export default getPdf;
相关文章:

导出为PDF加封面且分页处理dom元素分割
文章目录 正常展示页面导出后效果代码 正常展示页面 导出后效果 代码 组件内 <template><div><div><div class"content" id"content" style"padding: 0px 20px"><div class"item"><divstyle"…...

【C++入门】浅谈类、对象和 this 指针
文章目录 一、前言二、类1. 基本概念2. 类的封装3. 使用习惯成员函数定义习惯成员变量命名习惯 三、对象1. 基本概念2. 类对象的存储规则 四、this 指针1. 基本概念2. 注意事项3. 经典习题4. 常见面试题 一、前言 在 C 语言中,我们用结构体来描述一个事物的多种属性…...

【Linux命令200例】indent对C语言代码进行缩进和格式化
🏆作者简介,黑夜开发者,全栈领域新星创作者✌,2023年6月csdn上海赛道top4。 🏆本文已收录于专栏:Linux命令大全。 🏆本专栏我们会通过具体的系统的命令讲解加上鲜活的实操案例对各个命令进行深入…...

Hive 调优集锦(1)
一、前言 1.1 概念 Hive 依赖于 HDFS 存储数据,Hive 将 HQL 转换成 MapReduce 执行,所以说 Hive 是基于Hadoop 的一个数据仓库工具,实质就是一款基于 HDFS 的 MapReduce 计算框架,对存储在HDFS 中的数据进行分析和管理。 1.2 架…...

【C++详解】——智能指针
目录 为什么需要智能指针 抛异常引发内存泄漏 内存泄漏 什么是内存泄漏,内存泄漏的危害 内存泄漏分类 检测内存泄漏常用工具 如何避免内存泄漏 智能指针的使用及原理 RAII 智能指针的原理 各类智能指针介绍 auto_ptr unique_ptr shared_ptr weak_ptr …...

Jmeter接口/性能测试,Jmeter使用教程(超细整理)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、线程组 线程组…...
59,综合案例-演讲比赛流程管理系统
演讲比赛流程管理系统 59.1案例描述59.1.1比赛规则59.1.2程序功能 59.2创建管理类59.3菜单功能59.3.1添加成员函数59.3.2菜单功能实现 59.4退出功能59.4.1提供功能接口59.4.2实现退出功能 59.5演讲比赛功能59.5.1创建选手类59.5.2比赛59.5.2.1成员属性添加59.5.2.2初始化属性59…...

前端JS 展示上传图片缩略图(本地图片读取)
需求: 点击上传图片按钮,选择图片以后,不请求后端接口,直接将图片展示在缩略图中。 解决方案: 使用 FileReader 和 FileReader 中的 readAsDataURL 方法。 第一步 从input[type“file”] (上传文件标签) 里面拿到fil…...

Vue中$route和$router的区别
$router:用来操作路由,$route:用来获取路由信息 $router其实就是VueRouer的实例,对象包括了vue-router使用的实例方法,还有实例属性,我们可以理解为$router有一个设置的含义,比如设置当前的跳转…...

基于多任务学习卷积神经网络的皮肤损伤联合分割与分类
文章目录 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network摘要本文方法实验结果 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network 摘要 在…...

串口环形缓冲区
文章目录 一、串口环形缓冲区概念二、STC12例程(1)环形串口缓冲区结构体(2)串口环形缓冲区存和取数据(3)完整工程demo 一、串口环形缓冲区概念 串口环形缓冲区应用于嵌入式、物联网开发中处理接收串口数据…...

【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio完成简易通讯录
目录 🔆Cloud Studio 简介 操作步骤 1.登录 2.创建工作空间 3.初始界面 4.开发空间 5.保存自定义模板 🔆简易通讯录 1.实验要求 2.操作环境 3.源代码介绍 3.1 定义通讯录类 3.2 定义通讯录列表 3.3 添加联系人功能 3.4 修改联系人 3.5 …...

【技术积累】Vue.js中的核心知识
Vue的生命周期 Vue中的生命周期是指组件从创建到销毁的整个过程中,会触发一系列的钩子函数 Vue2中的生命周期 Vue2中的生命周期钩子函数是在组件的不同阶段执行的特定函数。这些钩子函数允许开发者在组件的不同生命周期阶段执行自定义的逻辑。 Vue2中的生命周期钩…...
flutter开发实战-显示本地图片网络图片及缓存目录图片
flutter开发实战-显示本地图片网络图片及缓存目录图片 在最近开发中碰到了需要显示缓存目录图片,这里顺便整理一下,显示本地图片、网络图片、缓存目录图片的方法。 一、工程本地图片显示 1 在项目根目录下创建名为 images文件夹,也可以将i…...
面对未来的算法备案法规:企业需要做哪些准备?
在信息时代,算法已经成为我们生活的一部分,涵盖了诸如搜索引擎、社交媒体、电子商务、广告投放等各个方面。然而,随着算法的广泛应用,其带来的问题也日益凸显。这引发了全球范围内的关注,未来的算法备案法规正在酝酿之…...

iptables的备份和还原
iptables的备份和还原 1、写在命令行当中的都是临时设置 2、把规则配置写在服务的文件当中,形成永久有效 备份:把iptables里面所有的配置都保存在/opt/ky30.bak中 iptables-save > /opt/ky30.bak 例: 默认配置文件在/etc/sysconfig/ip…...

easyUI框架学习
文章目录 一、前言二、引入使用easyUI 三、用法3.1 Dialog(对话框窗口)3.1.1 示例13.1.2 示例2 3.2 Layout(布局)3.2.1 示例1——通过标签创建布局3.2.2 示例2—— 创建嵌套布局 3.3 DateBox(日期输入框)3.…...

加入气压计模组,星斗3号将实现快速三维定位
随着信息技术的飞速发展,人们的生活正在发生巨大改变,人们对基于位置服务的需求越来越迫切,尤其是室内位置服务。 室外定位系统中BDS系统、GPS系统等受室内复杂环境条件限制精度大幅下降甚至失效,难以在室内定位中发挥作用,而室内二维定位技术缺乏高程信息,也难以满足人们对室…...

华为HCIP第二节-------------------------ISIS
IS-IS(Intermediate System to Intermediate System,中间系统到中间系统)是ISO (International Organization for Standardization,国际标准化组织)为它的CLNP(ConnectionLessNetwork Protocol&…...

在Mac系统下搭建Selenium环境并驱动Chrome浏览器
本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器,虽然会有坑,但是我们可以凭借敏捷的身手躲过。下面就开始吧: 安装selenium 打开终端 ->pip安装(安装命令:pip3 install selenium) 安装浏览…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...