antDv table组件滚动截图方法的实现
在开发中经常遇到table内容过多产生滚动的场景,正常情况下不产生滚动进行截图就很好实现,一旦产生滚动就会变得有点棘手。
下面分两种场景阐述解决的方法过程
场景一:右侧不固定列的情况

场景二:右侧固定列的情况

场景一
打开控制台我们发现表格的dom节点结构是这样子的


可以看到上面这两块内容并不是在同一个div下的,而是分两块div

那我们截图获取dom的时候当然不能获取他们俩共同的父级div,这样截图的图滚动隐藏的那部分就消失不见了

看到了吧 他就只有一部分,显然这是不符合要求的。所以我们下一步要做的就是 “拆分重组”!!
第一步 获取需要截图的dom节点

第二步 获取页面上截图区域的dom节点,这里需要注意的是这里不能直接创建dom元素必须要在template上写上dom节点,然后再获取


不能直接这样创建,这样会导致截图传入的时候会报错说无法在页面找到该节点

这样子创建是不行的哈,注意注意!!!
第三步 重组 将获取到的子节点添加到父节点中

注意不能这样子的哦 ,要使用cloneNode进行节点克隆,不可以直接在太岁头上动土的哦!!

第四步 清理 判断若是截图区域存在子节点时,要先清理再重新重组,不然就会出现重叠的情况


这里使用的是for循环,使用foreach循环会出现节点清理不干净的情况


可以看到如果使用foeEach会出现残余的情况,导致截图是这样

这部分完整代码如下
const downloadImg = () => {// 获取所有的.ant-table-fixed节点元素const v1 = document.querySelectorAll(".ant-table-fixed");// 获取标题const vt = document.getElementById("table_title");// 获取副标题const vs = document.getElementById("table_sub_text");// 获取截图区域的dom节点let parentDom = document.querySelector(".table_body");let childNodes = parentDom.childNodes;if (parentDom && childNodes.length > 0) {for (let i = childNodes.length - 1; i >= 0; i--) {parentDom.removeChild(childNodes[i]);}}parentDom.appendChild(vt.cloneNode(true));parentDom.appendChild(vs.cloneNode(true));parentDom.appendChild(v1[0].cloneNode(true));parentDom.appendChild(v1[1].cloneNode(true));// console.log(parentDom);downloadImage({ node: parentDom, fileName: data.tableData.title });};
这里做一个优化,考虑到性能的问题,我们把清理子节点这步动作放在截图完成之后就把它清理完,优化后的代码是这样的
const downloadImg = () => {// 获取所有的.ant-table-fixed节点元素const v1 = document.querySelectorAll(".ant-table-fixed");// 获取标题const vt = document.getElementById("table_title");// 获取副标题const vs = document.getElementById("table_sub_text");// 获取截图区域的dom节点let parentDom = document.querySelector(".table_body");let childNodes = parentDom.childNodes;parentDom.appendChild(vt.cloneNode(true));parentDom.appendChild(vs.cloneNode(true));parentDom.appendChild(v1[0].cloneNode(true));parentDom.appendChild(v1[1].cloneNode(true));// console.log(parentDom);downloadImage({ node: parentDom, fileName: data.tableData.title }, () => {if (parentDom && childNodes.length > 0) {for (let i = childNodes.length - 1; i >= 0; i--) {parentDom.removeChild(childNodes[i]);}}});};
附上样式代码
.table_body {position: absolute;top: 1000px;display: flex;flex-direction: column;justify-content: center;align-items: center;.title {font-size: 22px;font-family: "Source Han Sans CN";font-weight: 500;color: #061a19;}.sub-text {margin: 6px 0 16px;font-size: 16px;font-family: "Source Han Sans CN";font-weight: 400;color: #1d2f2e;}
}
这里需要指出的是,因为这截图的dom节点不能在页面呈现出来, 就使用障眼法,利用绝对定位使其脱离文档流布局。
场景二
场景二相比如场景一又比较复杂,基本方法与上面场景一叙述的一样,这里不加以赘述,只阐述场景二特有的难点。
如果用场景一的方法,对于场景二产生的效果是这样的

看到没 这里缺失了 不单单右侧的缺失了 连隐藏的那部分也都缺失了。所以我们又要来看它底层的dom是怎么构成的
研究发现,这右侧是多了这么个玩意,才导致列数缺失

同样地,我们就找到这个节点,然后把这个节点去掉

获取根节点后,内部结构是这样的

下面将对这三部分做处理
let fixRight = parentDom.querySelectorAll(".ant-table-cell-fix-right");for (let i = fixRight.length - 1; i >= 0; i--) {// 这里是解决右侧固定截图不完整的bugfixRight[i].attributes.style.nodeValue = "text-align: center; position: unset; right: 0px;";fixRight[i].attributes.style.textContent = "text-align: center; position: unset; right: 0px;";fixRight[i].attributes.style.value = "text-align: center; position: unset; right: 0px;";fixRight[i].attributes.class.nodeValue = "ant-table-align-center ant-table-row-cell-break-word ant-table-cell-fix-right-first;";fixRight[i].attributes.class.textContent = "ant-table-align-center ant-table-row-cell-break-word ant-table-cell-fix-right-first;";fixRight[i].attributes.class.value = "ant-table-align-center ant-table-row-cell-break-word ant-table-cell-fix-right-first";}
最终实现的效果是这样的

完美呈现,给自己个赞呀!!!!
最后奉上完整代码
const handleDownloadImage = () => {const v1 = document.querySelectorAll(".ant-table-fixed");const vt = document.getElementById("table_title");const vs = document.getElementById("table_sub_text");let parentDom = document.querySelector(".table_body");let childNodes = parentDom.childNodes;parentDom.appendChild(vt.cloneNode(true));parentDom.appendChild(vs.cloneNode(true));parentDom.appendChild(v1[0].cloneNode(true));parentDom.appendChild(v1[1].cloneNode(true));let fixRight = parentDom.querySelectorAll(".ant-table-cell-fix-right");for (let i = fixRight.length - 1; i >= 0; i--) {// 这里是解决右侧固定截图不完整的bugfixRight[i].attributes.style.nodeValue = "text-align: center; position: unset; right: 0px;";fixRight[i].attributes.style.textContent = "text-align: center; position: unset; right: 0px;";fixRight[i].attributes.style.value = "text-align: center; position: unset; right: 0px;";fixRight[i].attributes.class.nodeValue = "ant-table-align-center ant-table-row-cell-break-word ant-table-cell-fix-right-first;";fixRight[i].attributes.class.textContent = "ant-table-align-center ant-table-row-cell-break-word ant-table-cell-fix-right-first;";fixRight[i].attributes.class.value = "ant-table-align-center ant-table-row-cell-break-word ant-table-cell-fix-right-first";}downloadImage({ node: parentDom, fileName: title }, () => {if (parentDom && childNodes.length > 0) {for (let i = childNodes.length - 1; i >= 0; i--) {parentDom.removeChild(childNodes[i]);}}});
};
完…,现在周五20:40分,要去寻找光了!!!!
相关文章:
antDv table组件滚动截图方法的实现
在开发中经常遇到table内容过多产生滚动的场景,正常情况下不产生滚动进行截图就很好实现,一旦产生滚动就会变得有点棘手。 下面分两种场景阐述解决的方法过程 场景一:右侧不固定列的情况 场景二:右侧固定列的情况 场景一 打开…...
JavaSE【抽象类和接口】(抽象类、接口、实现多个接口、接口的继承)
一、抽象类 在 Java 中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用 给出具体的实现体。 1.语法 // 抽象类:被 abstract 修饰的类 public abstract class Shape { …...
微信小程序如何跳转H5页面
1、登录微信公众后台,进入【开发->开发管理->业务域名】,点击修改。 2、首先请下载校验文件,并将文件放置在域名根目录下。 我是把文件放在nginx主机的data目录下,然后通过增加nginx.config配置,重启nginx后可…...
C++(20):bit_cast
C++20之前如果想对不同的指针之间做类型转换需要通过reinterpret_cast,对于整数与指针之前的转换也需要通过reinterpret_cast: C++:reinterpret_cast_c++ reparant_cast_风静如云的博客-CSDN博客 但是reinterpret_cast的缺点是不同的编译环境下,无法包装转型的安全一致。 …...
STM32 低功耗-停止模式
STM32 停止模式 文章目录 STM32 停止模式第1章 低功耗模式简介第2章 停止模式简介2.1 进入停止模式2.1 退出停止模式 第3章 停止模式程序部分总结 第1章 低功耗模式简介 在 STM32 的正常工作中,具有四种工作模式:运行、睡眠、停止以及待机模式。 在系统…...
Hutool中 常用的工具类和方法
文章目录 日期时间工具类 DateUtil日期时间对象-DateTime类型转换工具类 Convert字符串工具类 StrUtil数字处理工具类 NumberUtilJavaBean的工具类 BeanUtil集合操作的工具类 CollUtilMap操作工具类 MapUtil数组工具-ArrayUtil唯一ID工具-IdUtilIO工具类-IoUtil加密解密工具类 …...
K8s(健康检查+滚动更新+优雅停机+弹性伸缩+Prometheus监控+配置分离)
前言 快速配置请直接跳转至汇总配置 K8s SpringBoot实现零宕机发布:健康检查滚动更新优雅停机弹性伸缩Prometheus监控配置分离(镜像复用) 配置 健康检查 健康检查类型:就绪探针(readiness) 存活探针&am…...
Django学习记录:使用ORM操作MySQL数据库并完成数据的增删改查
Django学习记录:使用ORM操作MySQL数据库并完成数据的增删改查 数据库操作 MySQL数据库pymysql Django开发操作数据库更简单,内部提供了ORM框架。 安装第三方模块 pip install mysqlclientORM可以做的事: 1、创建、修改、删除数据库中的…...
React Hooks 中的 useEffect(副作用)
useEffect 是什么? useEffect 是一个 React Hook,它允许你将组件与外部系统同步 当我们在 React 中使用 useEffect 这个 Hook 时,实际上是在告诉 React 在特定情况下执行我们定义的副作用函数。这种副作用函数可以处理一些与组件渲染结果无关…...
[CKA]考试之持久化存储卷PersistentVolume
由于最新的CKA考试改版,不允许存储书签,本博客致力怎么一步步从官网把答案找到,如何修改把题做对,下面开始我们的 CKA之旅 题目为: Task 创建一个pv,名字为app-config,大小为2Gi,…...
基于LLM的SQL应用程序开发实战(一)
基于LLM的SQL应用程序开发实战(一) 16.1 SQL on LLMs应用程序初始化 本节主要从案例代码的角度切入,探索ChatGPT以及大模型,尤其是从生产环境的视角,来思考具体的最佳实践。本节主要跟大家谈的是,在LangChain这样一个框架下,我们使用GPT-3.5或者GPT-4大模型,同时使用第…...
如何批量实现多行合并后居中
思路: 1.先填充数据 2.数据分类统计制作格式 3.格式刷刷制作出的格式 1.填充数据 思路:选中,F5定位空值,,⬆(键盘上的上下左右哪里的上键),按住Ctrl然后按Enter。 2.数据分类统计…...
【深度学习_TensorFlow】手写数字识别
写在前面 到这里为止,我们已经学习完张量的常用操作方法,已具备实现大部分神经网络技术的基础储备了。这一章节我们将开启神经网络的学习,然而并不需要像学习前面那样了解大量的张量操作,而是将重点转向理解概念知识,…...
antv/l7地图,鼠标滚动,页面正常滑动-- 我们忽略的deltaY
背景 在官网项目中,需要使用一个地图,展示产品的分布区域及数量。希望的交互是,鼠标放上标点,tooltip展示地点和数量等信息。鼠标滚动,则页面随着滚动。但是鼠标事件是被地图代理了的,鼠标滚动意味着地图的…...
再续AM335x经典,米尔TI AM62x核心板上市,赋能新一代HMI
近十年来,AM335x芯片作为TI经典工业MPU产品,在工业处理器市场占据主流地位,其凭借GPMC高速并口、PRU协处理器等个性化硬件资源,在工业控制、能源电力、轨道交通、智慧医疗等领域广受用户欢迎。随着信息技术的快速发展,…...
springboot和Django哪一个做web服务器框架更好
目录 一、两者特点 二、各自优势 一、两者特点 编程语言: Spring Boot:使用 Java 编程语言。Django:使用 Python 编程语言。 生态系统和社区支持: Spring Boot:具有庞大的 Java 生态系统和强大的社区支持。适用于大型…...
C#核心知识回顾——21.归并排序
理解递归逻辑 一开始不会执行sort函数的 要先找到最小容量数组时 才会回头递归调用Sort进行排序 基本原理 归并 递归 合并 数组分左右 左右元素相比较 一侧用完放对面 不停放入新数组 递归不停分 分…...
基于netty的rpc远程调用
QPRC 🚀🚀🚀这是一个手写RPC项目,用于实现远程过程调用(RPC)通信🚀🚀🚀 欢迎star串门:https://github.com/red-velet/ 🚀Q-PRC 一、功能特性 …...
RabbitMQ输出日志配置
参考地址rabbitmq启用日志功能记录消息队列收发情况_rabbitmq开启日志_普通网友的博客-CSDN博客 启用日志插件命令 # 设置用户权限 rabbitmqctl set_user_tags mqtt-user administrator rabbitmqctl set_permissions -p / mqtt-user ".*" ".*" ".*&…...
解决一个Sqoop抽数慢的问题,yarn的ATSv2嵌入式HBASE崩溃引起
新搭建的一个Hadoop环境,用Sqoop批量抽数的时候发现特别慢,我们正常情况下是一个表一分钟左右,批量抽十几个表,也就是10分钟的样子,结果发现用了2个小时: 查看yarn日志 发现有如下情况: 主要有两…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
