excell导入十万数据慢该如何解决

1.遇到的问题
项目中遇到导入6w条数据,之前用的poi,感觉很慢,这时查询了下阿里巴巴提供了开源的easyExcell很好用。
EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel
2.读写速度
64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本)

3.代码实现
代码出处:读Excel | Easy Excel
最简单的读取对象
@Getter
@Setter
@EqualsAndHashCode
public class DemoData {private String string;private Date date;private Double doubleData;
}
最简单的监听器
// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Slf4j
public class DemoDataListener implements ReadListener<DemoData> {/*** 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 100;/*** 缓存的数据*/private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。*/private DemoDAO demoDAO;public DemoDataListener() {// 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数demoDAO = new DemoDAO();}/*** 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来** @param demoDAO*/public DemoDataListener(DemoDAO demoDAO) {this.demoDAO = demoDAO;}/*** 这个每一条数据解析都会来调用** @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context*/@Overridepublic void invoke(DemoData data, AnalysisContext context) {log.info("解析到一条数据:{}", JSON.toJSONString(data));cachedDataList.add(data);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}/*** 所有数据解析完成了 都会来调用** @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();log.info("所有数据解析完成!");}/*** 加上存储数据库*/private void saveData() {log.info("{}条数据,开始存储数据库!", cachedDataList.size());demoDAO.save(cachedDataList);log.info("存储数据库成功!");}
}
持久层,自己实现批量插入,也可以使用多线程插入。
异步线程配置:
# 异步线程配置 # 核心线程数 async:executor:thread:core_pool_size: 10# 最大线程数max_pool_size: 100# 任务队列大小queue_capacity: 20# 线程池中线程的名称前缀name:prefix: kc-async-service-# 缓冲队列中线程的空闲时间keep_alive_seconds: 100await_termination_seconds: 60
/*** 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。**/
public class DemoDAO {public void save(List<DemoData> list) {// 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入}
}
代码
/*** 最简单的读* <p>* 1. 创建excel对应的实体对象 参照{@link DemoData}* <p>* 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}* <p>* 3. 直接读即可*/@Testpublic void simpleRead() {// 写法1:JDK8+ ,不用额外写一个DemoDataListener// since: 3.0.0-beta1String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行// 具体需要返回多少行可以在`PageReadListener`的构造函数设置EasyExcel.read(fileName, DemoData.class, new PageReadListener<DemoData>(dataList -> {for (DemoData demoData : dataList) {log.info("读取到一条数据{}", JSON.toJSONString(demoData));}})).sheet().doRead();// 写法2:// 匿名内部类 不用额外写一个DemoDataListenerfileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, DemoData.class, new ReadListener<DemoData>() {/*** 单次缓存的数据量*/public static final int BATCH_COUNT = 100;/***临时存储*/private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);@Overridepublic void invoke(DemoData data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {saveData();}/*** 加上存储数据库*/private void saveData() {log.info("{}条数据,开始存储数据库!", cachedDataList.size());log.info("存储数据库成功!");}}).sheet().doRead();// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去// 写法3:fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();// 写法4fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 一个文件一个readertry (ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build()) {// 构建一个sheet 这里可以指定名字或者noReadSheet readSheet = EasyExcel.readSheet(0).build();// 读取一个sheetexcelReader.read(readSheet);}}
指定列读取例子
@Getter
@Setter
@EqualsAndHashCode
public class IndexOrNameData {/*** 强制读取第三个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配*/@ExcelProperty(index = 2)private Double doubleData;/*** 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据*/@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;
}
4.总结
EasyExcell效率很高,使用这种方式性能提高很多。
相关文章:
excell导入十万数据慢该如何解决
1.遇到的问题 项目中遇到导入6w条数据,之前用的poi,感觉很慢,这时查询了下阿里巴巴提供了开源的easyExcell很好用。 EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 2.读写速度 64M内存20秒读取75M(46W行25列)的Excel&#x…...
Python异步编程常见问题与解决
Python异步编程常见问题与解决 在当今的互联网应用中,异步编程成为了一种非常重要的技术。在Python中,我们可以利用异步编程来提高应用的性能和响应能力。然而,异步编程也会带来一些常见的问题。本文将向你分享一些在Python中处理异步编程的…...
77. 组合
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2: 输入:n 1, k 1 输出…...
vue项目开发环境工具-node
最近在开始接触做vue框架的前端项目,以前用的前端比如html,js,css等都是比较原生的,写好后直接浏览器打开就行。但vue跟java一样是需要编译的,和微信小程序类似。今天就先记录一下vue的开发运行搭建。所需工具如下 nod…...
Python | 为FastAPI后端服务添加API Key认证(分别基于路径传参和header两种方式且swagger文档友好支持)
文章目录 01 前言02 路径传参方式添加API Key2.1 完整代码2.2 请求示例2.3 swagger文档测试 03 请求头Header方式传入API Key(推荐)3.1 完整代码3.2 请求示例3.3 swagger文档测试 01 前言 FastAPI,如其名所示,是一个极为高效的框…...
nodeJs+jwt实现小程序tonken鉴权
nodeJsjwt实现小程序tonken鉴权 自我记录 config\config.js // 配置文件 module.exports {DBHOST: 127.0.0.1,DBPORT: 27017,DBNAME: test,secret: xxxxx,// 小程序的appSecretAppID: xxxxx,// 小程序的appId }token中间件 middlewares\checkTokenMiddleware.js //导入 jwt…...
更新andriod studio版本,项目编译报could not find org.junit.jupiter:junit-jupiter
原本使用Android Studio 版本是4.1.1,现更新为 点击build -》 build bundle -》build apk,项目报 Could not determine the dependencies of task :app:compileDebugUnitTestJavaWithJavac. > Could not resolve all task dependencies for configur…...
【慕伏白教程】 Linux 深度学习服务器配置指北
文章目录 镜像烧录系统安装系统配置常用包安装 镜像烧录 下载 Ubuntu 镜像 Ubuntu 桌面版 下载烧录工具 balenaEtcher 准备至少 8G 的 空白U盘 开始烧录 系统安装 开机进入BIOS,修改U盘为第一启动 选择 Try or Install Ubuntu 往下拉,选择 中文&a…...
学习windows系统让python脚本在后台运行的方法
学习windows系统让python脚本在后台运行的方法 windows 后台运行并输出日志文件windows 前台运行并输出日志文件 windows 后台运行并输出日志文件 命令: python qipa250.py >> qipa250_logs.log 2>&1 &窗口关闭后程序也就关闭了 windows 前台运…...
华为OD机试 - 第k个排列 - 全排列递归(Java 2023 B卷 100分)
目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…...
流媒体播放器EasyPlayer.js无法播放H.265的情况是什么原因?该如何解决?
H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,可支持H.264与H.265编码格式,性能稳定、播放流畅,能支持WebSocket-FLV、HTTP-FLV,HLS(m3u8&#…...
负载均衡器监控
什么是负载均衡器 负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企…...
【计算机视觉】2.图像特征提取
图像特征提取 一、颜色特征量化颜色直方图聚类颜色直方图 二、边缘特征边缘边缘定义边缘提取边缘精细 三、特征点的特征描述子Harris角点FAST角点斑点SIFTHaar-like特征SURFORBLBPGabor 一、颜色特征 量化颜色直方图 HSV空间 优势:计算高效 劣势:量化问…...
华为存储培训
01 存储前沿技术和发展趋势 狭义的存储定义 CD、DVD、ZIP、磁带、硬盘等 广义的存储定义 存储硬件系统(磁盘阵列,控制器,磁盘柜,磁带库等) 存储软件(备份软件;管理软件,快照&…...
I帧、P帧,B帧,GOP
doGetNextFrame() 在Live555库的FramedSource类中,数据帧的获取位置由doGetNextFrame()函数来设置。这个函数是一个虚函数,子类可以重写它以实现特定类型的数据帧获取逻辑。 在FramedSource的子类中,你可以重写doGetNextFrame()函数&#x…...
Apache DolphinScheduler在中国信通院“2023 OSCAR开源尖峰案例”评选中荣获「尖峰开源项目奖」!
在近日由中国信息通信研究院(以下简称“中国信通院”)和中国通信标准化协会联合主办的“2023 OSCAR 开源产业大会”上,主办方公布了 2023 年“OSCAR 开源尖峰案例”评选结果,包括“开源人物”“开源项目”“开源社区”“开源企业”…...
Java Lambda 表达式
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! Java Lambda 表达式 Java Lambda 表达式是 Java 8 引入的一种函数式编程特性,它是一种轻量级的匿名函数,允许我们将函数作为方法的参数进行传递…...
数据结构--插入排序
目录 插入排序 算法实现 算法效率分析 插入排序的优化-折半插入排序 最终的结果:(方式) 优化-折半查找的代码实现 回顾 插入排序 算法实现 算法效率分析 空间复杂度和问题规模无关 插入排序的优化-折半插入排序 之前的元素有序&am…...
服务器搭建(TCP套接字)-epoll版(服务端)
epoll 是一种在 Linux 系统上用于高效事件驱动编程的 I/O 多路复用机制。它相比于传统的 select 和 poll 函数具有更好的性能和扩展性。 epoll 的主要特点和原理: 1、事件驱动:epoll 是基于事件驱动的模型,它通过监听事件来触发相应的回调函…...
第一章:最新版零基础学习 PYTHON 教程(第十八节 - Python 表达式语句–Python 中的中断、继续和传递)
在 Python 中使用循环可以高效地自动执行和重复任务。但有时,可能会出现您想要完全退出循环、跳过迭代或忽略该条件的情况。这些可以通过循环控制语句来完成。循环控制语句改变其正常顺序的执行。当执行离开作用域时,在该作用域中创建的所有自动对象都将被销毁。Python支持以…...
构建智能体的专业技能树 - Agent Skills生态全析(中篇)
一、概述 这篇文章我们将围绕Skills、Tools、MCP、Subagents 四个组件有什么区别、Anthropic 官方做好了哪些现成 Skills、如何从零创建一个自定义 Skill 的完整流程 这些四个方面来进行讲解。 二、智能体生态系统概览 在 Anthropic 构建的智能体生态中,多种技术组件…...
从PolarCTF一道Crypto题,聊聊如何用SageMath秒解自定义群运算的离散对数问题
从PolarCTF一道Crypto题看SageMath在离散对数问题中的实战应用 1. 密码学竞赛中的非标准群运算挑战 在CTF密码学题目中,自定义群运算的离散对数问题(DLP)是常见的高频考点。近期PolarCTF竞赛中出现了一道典型题目,要求参赛者在非…...
新手福音:用快马AI生成带详解注释的Arduino交通灯实验代码
作为一个刚接触单片机的新手,第一次看到Arduino开发板时既兴奋又迷茫。那些闪烁的LED灯和蜂鸣器背后到底藏着什么秘密?今天我就用InsCode(快马)平台来探索一个有趣的交通灯模拟项目,整个过程比想象中简单多了。 项目构思 我想做一个能模拟真实…...
Git子模块更新报错?手把手教你解决‘Unable to find origin/master revision‘问题
Git子模块更新报错深度解析:从原理到实战解决方案 1. 问题现象与核心原因分析 当你执行git submodule update --remote命令时,突然遇到fatal: Unable to find current origin/master revision in submodule path错误提示,这种场景在团队协作…...
ESP32S3-Cam + MPU6050 DMP移植避坑实录:从编译报错到姿态数据稳定输出的完整流程
ESP32S3-Cam与MPU6050 DMP移植实战:从编译报错到稳定姿态解算的全流程解析 当ESP32S3-Cam遇上MPU6050的DMP(数字运动处理器)功能,本应是物联网项目中实现低成本姿态检测的完美组合。但实际移植过程中,开发者往往会遭遇…...
GLM-4.1V-9B-Base行业实践:农业病虫害田间照片识别与防治建议辅助
GLM-4.1V-9B-Base行业实践:农业病虫害田间照片识别与防治建议辅助 1. 农业场景下的视觉AI需求 在现代农业生产中,病虫害防治一直是困扰农户的核心问题。传统识别方法依赖农技人员现场勘查,效率低下且成本高昂。根据农业农村部数据ÿ…...
终极指南:Czkawka开源文件管理工具,5分钟解决存储空间不足难题
终极指南:Czkawka开源文件管理工具,5分钟解决存储空间不足难题 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 你是否经常遇…...
Qwen3.5-9B-AWQ-4bit开源可部署教程:私有云/K8s集群中部署多实例视觉理解服务
Qwen3.5-9B-AWQ-4bit开源可部署教程:私有云/K8s集群中部署多实例视觉理解服务 1. 模型概述 Qwen3.5-9B-AWQ-4bit是一个支持图像理解的多模态模型,能够结合上传图片与文字提示词,输出中文分析结果。这个量化版本特别适合在资源受限的环境中部…...
Qwen2.5-VL-7B-Instruct开源大模型:支持中文优先的多模态理解部署方案
Qwen2.5-VL-7B-Instruct开源大模型:支持中文优先的多模态理解部署方案 1. 项目概述 Qwen2.5-VL-7B-Instruct是一款开源的视觉-语言多模态大模型,特别针对中文场景进行了优化。该模型能够同时处理图像和文本输入,实现跨模态的理解与生成任务…...
Android tinyalsa深度解析之pcm_params_get_periods_min调用流程与实战(一百七十三)
简介: CSDN博客专家、《Android系统多媒体进阶实战》作者 博主新书推荐:《Android系统多媒体进阶实战》🚀 Android Audio工程师专栏地址: Audio工程师进阶系列【原创干货持续更新中……】🚀 Android多媒体专栏地址&a…...
