【Alibaba工具型技术系列】「EasyExcel技术专题」实战研究一下 EasyExcel 如何从指定文件位置进行读取数据
实战研究一下 EasyExcel 如何从指定文件位置进行读取数据
- EasyExcel的使用背景
- EasyExcel的时候痛点
- EasyExcel对比其他框架
- EasyExcel的编程模式
- EasyExcel读取的指定位置
- 导入数据的流程
- 表头校验
- invokeHeadMap()方法
- 数据处理
- invoke()方法
- 执行中断
- hasNextdoAfterAllAnalysed()方法
- 数据完成
- doAfterAllAnalysed()方法
- 总结一下
EasyExcel的使用背景
工作中总会遇到对Excel读写功能,之前接触过EasyExcel,后续我们基本上用它代替了传统的POI和JXL、甚至还有一个EasyPOI技术。
EasyExcel的时候痛点
使用的EasyExcel时候,一般场景下表头比较传统,也不复杂,但是这次呢表头稍微有点复杂,读取数据要从指定的位置开始,要从指定位置开始读取EasyExcel,所以呢在不断的摸索之后,找到了合适的解决方法。
EasyExcel对比其他框架
平常用poi读取excel数据量少,加上EasyExcel读取Excel有点复杂,所以一直也没在项目中使用EasyExcel,直到有一回要读取的数据量太大,使用poi读取Excel在创建Workbook -> WorkbookFactory.create(inputStream) 时就异常了,分配很多内存也不好使,所以放弃使用poi转使用EasyExcel。
Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。
在上层做了模型转换的封装,让使用者更加简单方便 --EasyExcel
使用EasyExcel读取Excel时一直在想如何简化读取方式,不用读取每个Excel都创建一个XXDataListene监听器类,刚开始想,把DataListener加上泛型,共用一个DataListener,但是还涉及到如何传递Dao和每个Dao如何保存数据,而且保存数据前可能还需要对数据进行不同的处理。
EasyExcel的编程模式
EasyExcel开源挺久了,但使用上感觉有点让人望而生怯,刚开始看官方文档上读取Excel挺简单的,只需要一行代码,继续细看的话还需要创建一个回调监听器,有点复杂呀(每个Excel都需要创建一个单独的回调监听器类)。
EasyExcel读取的指定位置
要开始读取数据,第8行才是真正的数据,直接上代码,headRowNumber(),不写默认是1,即就是从第二行开始读数据。
/*** 读取文件信息数据* @param filePath* @param headNum*/public ContactInfoExcelDataListener read(String filePath , int headNum){EasyExcel.read(filePath, this).head(ContactInfoExcelEntity.class).autoCloseStream(true).autoTrim(true).ignoreEmptyRow(true).sheet()// 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,因为默认会根据DemoData 来解析,他没有指定头,也就是默认1行.headRowNumber(Math.max(headNum,NumberUtils.BYTE_ZERO)).doRead();return this;}/*** 读取文件信息数据* @param filePath*/public ContactInfoExcelDataListener read(String filePath){EasyExcel.read(filePath, this).head(ContactInfoExcelEntity.class).autoCloseStream(true).autoTrim(true).ignoreEmptyRow(true).sheet()// 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,因为默认会根据DemoData 来解析,他没有指定头,也就是默认1行.doRead();return this;}/*** 读取文件信息数据* @param inputStream* @param headNum*/public ContactInfoExcelDataListener read(InputStream inputStream, int headNum){EasyExcel.read(inputStream, this).head(ContactInfoExcelEntity.class).autoCloseStream(true).autoTrim(true).ignoreEmptyRow(true).sheet()// 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,因为默认会根据DemoData 来解析,他没有指定头,也就是默认1行.headRowNumber(Math.max(headNum,NumberUtils.BYTE_ZERO)).doRead();return this;}
导入数据的流程
基本都会走到这里,全部放权交接给invoke方法,并且巧用作为我们锁初始化操作的控制赋值,切记如果headNum = 0 此方法很有可能不会触发,慎用!
表头校验
目前只是实现了相关的单节点同步锁,如果未来扩展了相关的分布式节点,需要采用分布式锁机制进行控制!锁范围需要进行控制
invokeHeadMap()方法
/*** 调用头部* @param map* @param analysisContext*/@Overridepublic void invokeHead(Map<Integer, CellData> map, AnalysisContext analysisContext) {log.info("【start read the excel head data】:{}",map);// 判断标记头是否存在try {int titleRows = map.size();// 头部的中断处理机制!failureDataCount = preValidate?orginalHead.size() != titleRows?NumberUtils.INTEGER_ONE:NumberUtils.BYTE_ZERO:NumberUtils.BYTE_ZERO;// 进行置位if(preValidate && (failureDataCount.intValue() == NumberUtils.INTEGER_ONE)){causeByHeadFormatAbort = Boolean.TRUE;}if(!isMockFlag) {// TODO 基本不会走到这里:一般我们如果需要可以使用此方法作为初始化资源使用的目的!//Preconditions.checkNotNull(clueLogic,"not support clueLogic is inject this class subject!");if (Objects.isNull(clueLogic)) {clueLogic = SpringUtils.getBean(ClueLogic.class);}customerImportVO = new CustomerImportVO();// 此部分主要是为了减少不必要的内存空间的申请tempDataList = Lists.newArrayListWithExpectedSize(batchSizeUnit);}
// syncLockController.lock();} catch (Exception e) {log.error("invoke the analysis the title head info data is failure!",e);throw new UnsupportedOperationException("invoke the analysis the title head info data is failure!",e);}log.info("【finished read the excel head data】");}
数据处理
invoke()方法
一条一条数据解析 invoke()方法 ,方法里面是我业务逻辑,数据校验。invoke 就是每行具体的数据值
/*** 调用操作处理控制机制* @param excelEntity* @param context*/@Overridepublic void invoke(ContactInfoExcelEntity excelEntity, AnalysisContext context) {log.info("----【start read the excel main data:{}】----",excelEntity);if(batchSizeUnit <= tempDataList.size()){CustomerImportVO customerImportVO = clueLogic.startCallTaskProxy(contactInfoImportParam,tempDataList);// 合并计算结果->更新为最新的结果this.customerImportVO.merge(customerImportVO);tempDataList.clear();tempDataList = Lists.newArrayListWithExpectedSize(batchSizeUnit);}else{tempDataList.add(excelEntity);}log.info("【finished read the excel main data】");}
执行中断
hasNextdoAfterAllAnalysed()方法
/*** 是否拥有下一次执行* [@param](https://my.oschina.net/u/2303379) context* [@return](https://my.oschina.net/u/556800)*/[@Override](https://my.oschina.net/u/1162528)public boolean hasNext(AnalysisContext context) {return causeByHeadFormatAbort?Boolean.FALSE:isSupportAbort? failureDataCount <= 0 :Boolean.TRUE;}
数据完成
doAfterAllAnalysed()方法
所有数据解析完, doAfterAllAnalysed()方法,里面写的有保存数据方法。
/*** 执行结束的回调机制* @param analysisContext*/@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {log.info("【doAfterAllAnalysed the process】");try {CustomerImportVO customerImportVO = clueLogic.startCallTaskProxy(contactInfoImportParam,tempDataList);this.customerImportVO.merge(customerImportVO);finisheDataResult = Boolean.TRUE;}catch (Exception e){log.error("execute finially the flush data is failure!");//TODO 收尾的数据信息如何做到一致性和完成补偿!finisheDataResult = Boolean.FALSE;} finally {tempDataList.clear();
// syncLockController.unlock();}}
总结一下
- 快速读写:EasyExcel 支持 Excel 2003 和 Excel 2007 格式,并提供高效的读写性能。它使用了 NIO(新输入/输出)技术,使得读写操作更加快速。
- 简单易用:EasyExcel 的 API 设计简洁明了,易于使用。开发者只需编写少量代码,即可完成 Excel 文件的读写操作。它还支持链式编程,使代码更加简洁。
- 支持自定义:EasyExcel 提供了丰富的自定义选项,允许开发者根据需要调整 Excel 文件的格式、样式等。它还支持自定义公式、条件格式等功能,满足各种业务需求。
- 灵活的配置:EasyExcel 支持多种配置方式,如属性配置、注解配置等。开发者可以根据项目需求选择合适的配置方式,使得 Excel 文件的处理更加灵活。
相关文章:

【Alibaba工具型技术系列】「EasyExcel技术专题」实战研究一下 EasyExcel 如何从指定文件位置进行读取数据
实战研究一下 EasyExcel 如何从指定文件位置进行读取数据 EasyExcel的使用背景EasyExcel的时候痛点EasyExcel对比其他框架 EasyExcel的编程模式EasyExcel读取的指定位置导入数据的流程表头校验invokeHeadMap()方法 数据处理invoke()方法 执行中断hasNextdoAfterAllAnalysed()方…...

java.security.InvalidKeyException: Illegal key size错误
出现的问题 最近在对接第三方,涉及获取token鉴权。在本地调试能获取到token,但是在Linux环境上调用就报错:java.security.InvalidKeyException: Illegal key size 与三方沟通 ,排除了是传参和网络的原因;搜索资料发现…...

python脚本,实现监控系统的各项资源
今天的文章涉及到docker的操作和一个python脚本,实现监控网络的流量、CPU使用率、内存使用率和磁盘使用情况。一起先看看效果吧: 这是在控制台中出现的数据,可以很简单的看到我们想要的监控指标。如果实现定时任务和数据的存储、数据的展示&a…...

Flink处理函数(2)—— 按键分区处理函数
按键分区处理函数(KeyedProcessFunction):先进行分区,然后定义处理操作 1.定时器(Timer)和定时服务(TimerService) 定时器(timers)是处理函数中进行时间相关…...

服务器数据恢复—服务器进水导致阵列中磁盘同时掉线的数据恢复案例
服务器数据恢复环境: 数台服务器数台存储阵列柜,共上百块硬盘,划分了数十组lun。 服务器故障&检测: 外部因素导致服务器进水,进水服务器中一组阵列内的所有硬盘同时掉线。 北亚数据恢复工程师到达现场后发现机房内…...

npm或者pnpm或者yarn安装依赖报错ENOTFOUND解决办法
如果报错说安装依赖报错,大概率是因为npm源没有设置对,比如我这里安装protobufjs的时候报错:ENOTFOUND npm ERR! code ENOTFOUND npm ERR! syscall getaddrinfo npm ERR! errno ENOTFOUND npm ERR! network request to https://registry.cnpm…...

学会使用ubuntu——ubuntu22.04使用Google、git的魔法操作
ubuntu22.04使用Google、git的魔法操作 转战知乎写作 https://zhuanlan.zhihu.com/p/679332988...

【机组】计算机组成原理实验指导书.
🌈个人主页:Sarapines Programmer🔥 系列专栏:《机组 | 模块单元实验》⏰诗赋清音:云生高巅梦远游, 星光点缀碧海愁。 山川深邃情难晤, 剑气凌云志自修。 目录 第一章 性能特点 1.1 系…...

解决Sublime Text V3.2.2中文乱码问题
目录 中文乱码出现情形通过安装插件来解决乱码问题 中文乱码出现情形 打开一个中文txt文件,显示乱码,在File->Reopen With Encoding里面找不到支持简体中文正常显示的编码选项。 通过安装插件来解决乱码问题 安装Package Control插件 打开Tool->…...

Oracle 12CR2 RAC部署翻车,bug避坑经历
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...

情绪共享机器:潜力与挑战
在设想的未来科技世界中,有一种神奇的机器,它能够让我们戴上后即刻感知并体验他人当下的情绪。这种情绪共享机器无疑将深刻地改变我们对人际关系、社会交互乃至人性本质的理解。然而,这一科技创新所带来的影响并非全然积极,也伴随…...

docker 安装python3.8环境镜像并导入局域网
一、安装docker yum -y install docker docker version #显示 Docker 版本信息 可以看到已经下载下来了 拉取镜像python3镜像 二、安装docker 中python3环境 运行本地镜像,并进入镜像环境 docker run -itd python-38 /bin/bash docker run -itd pyth…...

修复“电脑引用的账户当前已锁定”问题的几个方法,看下有没有能帮助到你的
面对“电脑引用的账户当前已锁定,且可能无法登录”可能会让你感到焦虑。这是重复输入错误密码后出现的登录错误。当帐户锁定阈值策略配置为限制未经授权的访问时,就会发生这种情况。 但是,如果你在等待半小时后输入正确的密码,你可以重新访问你的帐户。同样,如果你有一个…...

vp9协议笔记
vp9协议笔记📒 本文主要是对vp9协议的梳理,协议的细节参考官方文档:VP9协议链接(需要加速器) vp9协议笔记 vp9协议笔记📒1. 视频编码概述2. 超级帧superframe(sz):2. fr…...

信息检索与数据挖掘 | (九)Link Analysis(链接分析)
文章目录 📚链接分析📚随机矩阵📚random walk📚Google formulation 📚链接分析 将链接看做投票,从重要的网站来的链接其权重更高,所以是递归定义的。 如果网页j权重为rj,有n个出边&…...

yarn的安装及使用教程
Yarn 是一个快速、可靠、安全的包管理工具,用于管理 JavaScript 项目的依赖项。下面是关于 Yarn 的安装和基本使用的详细教程: 安装 Yarn 访问 Yarn 官网 并按照指示下载适合你操作系统的安装程序。安装程序会自动安装 Yarn,并将其添加到系…...

最新AI系统ChatGPT网站H5系统源码,支持Midjourney绘画,GPT语音对话+ChatFile文档对话总结+DALL-E3文生图
一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧。已支持GPT…...

学会使用ubuntu——ubuntu22.04使用WebCatlog
Ubuntu22.04使用WebCatlog WebCatlog是适用于Gnu / Linux,Windows或Mac OS X系统的桌面程序。 引擎基于铬,它用于在我们的桌面上处理Web服务。简单点就是把网页单独一个窗口出来显示,当一个app用。本文就是利用WebCatlog安装后的notion编写的…...

(Arcgis)Python3.8批量裁剪利用shp文件裁剪tif栅格影像数据
使用环境: pycharm2020 arcgis pro 中的python3.8 一、pycharm中设置python编译器。左上角“文件”——“设置”——找到python interpreter——找到arcgis pro安装文件夹中的python D:\ArcGIS Pro\bin\Python\envs\arcgispro-py3\python.exe使用arcgis pro原因&a…...

漏洞补丁修复之openssl版本从1.1.1q升级到1.1.1t以及python版本默认2.7.5升级到2.7.18新版本和Nginx版本升级到1.24.0
一、Openssl升级 1、查看Openssl安装的版本 openssl version 2、查看Openssl路径 which openssl 3、上传openssl安装包到服务器:openssl-1.1.1t.tar.gz,并且解压,安装: mv /usr/local/openssl /usr/local/backup_openssl_1.1.1q_20240120 mkdir /usr/local/openssl tar…...

HCIP-BGP实验4
搭建实验拓扑图 要求 1.全网可达 2.isp只能配置IP地址 实验开始 配置IP地址及环回 r1,r2,r9,r10配ipv4地址(以r1为例) [Huawei]sysname r1 [r1]interface g0/0/0 [r1-GigabitEthernet0/0/0]ip address 12.1.1.1 24 [r1-GigabitEthernet0/0/0]q [r1]interface LoopBack 0…...

数据挖掘笔记1
课程:清华大学-数据挖掘:理论与算法(国家级精品课)_哔哩哔哩_bilibili 一、Learning Resources 二、Data 数据是最底层的一种表现形式。数据具有连续性。从存储上来讲,数据分为逻辑上的和物理层的。大数据࿱…...

Spring RabbitMQ那些事(3-消息可靠传输和订阅)
目录 一、序言二、生产者确保消息发送成功1、为什么需要Publisher Confirms2、哪些消息会被确认处理成功 三、消费者保证消息被处理四、Spring RabbitMQ支持代码示例1、 application.yml2、RabbigtMQ配置3、可靠生产者配置4、可靠消费者配置5、测试用例 一、序言 在有些业务场…...

揭秘 Kafka 高性能之谜:一文读懂背后的设计精粹与技术实现
Kafka在性能方面有着显著的优势,这也使得Kafka的应用非常广泛,那kakfa的性能为何如此优异呢?本文将带你探寻kafka高性能之谜。 kafka的高性能概括起来有如下几点:顺序写入磁盘与I/O优化、批量处理、页缓存、零拷贝技术、分区并行处…...

canvas绘制美国国旗(USA Flag)
查看专栏目录 canvas实例应用100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…...

Python中的`__all__`魔法函数使用详解
概要 Python是一门灵活而强大的编程语言,提供了各种机制来控制模块的导入和访问。其中,__all__魔法函数是一种用于限制模块导入的机制,可以明确指定哪些变量、函数或类可以被导入。本文将深入探讨__all__的作用、用法以及示例,以…...

Studio One 6 mac 6.5.2 激活版 数字音乐编曲创作
PreSonus Studio One是PreSonus出品的一款功能强大的音乐创作软件。主要为用户提供音乐创作、录音、编辑、制作等功能。它可以让你创造音乐,无限的轨道,无限的MIDI和乐器轨道,虚拟乐器和效果通道,这些都是强大和完美的。 软件下载…...

GitHub图床TyporaPicGo相关配置
本文作者: slience_me 文章目录 GitHub图床&Typora&PicGo相关配置1. Github配置2. picGo配置3. Typora配置 GitHub图床&Typora&PicGo相关配置 关于Typora旧版的百度网盘下载路径 链接:https://pan.baidu.com/s/12mq-dMqWnRRoreGo4MTbKg?…...

FireAlpaca:轻量级、免费的Mac/Win绘图软件,让你的创意如火燃烧!
FireAlpaca是一款轻量级、免费的绘图软件,适用于Mac和Win系统,让你的创作过程更加快捷、简便。无论是绘制漫画、插图、设计作品还是进行简单的图片编辑,FireAlpaca都能满足你的需求。 首先,FireAlpaca具有直观友好的用户界面&…...

用 Python 制作可视化 GUI 界面,一键实现自动分类管理文件!
经常杂乱无章的文件夹会让我们找不到所想要的文件,因此小编特意制作了一个可视化GUI界面,通过输入路径一键点击实现文件分门别类的归档。 不同的文件后缀归类为不同的类别 我们先罗列一下大致有几类文件,根据文件的后缀来设定,大…...