当前位置: 首页 > news >正文

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条数据&#xff0c;之前用的poi&#xff0c;感觉很慢&#xff0c;这时查询了下阿里巴巴提供了开源的easyExcell很好用。 EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 2.读写速度 64M内存20秒读取75M(46W行25列)的Excel&#x…...

Python异步编程常见问题与解决

Python异步编程常见问题与解决 在当今的互联网应用中&#xff0c;异步编程成为了一种非常重要的技术。在Python中&#xff0c;我们可以利用异步编程来提高应用的性能和响应能力。然而&#xff0c;异步编程也会带来一些常见的问题。本文将向你分享一些在Python中处理异步编程的…...

77. 组合

给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2&#xff1a; 输入&#xff1a;n 1, k 1 输出…...

vue项目开发环境工具-node

最近在开始接触做vue框架的前端项目&#xff0c;以前用的前端比如html&#xff0c;js&#xff0c;css等都是比较原生的&#xff0c;写好后直接浏览器打开就行。但vue跟java一样是需要编译的&#xff0c;和微信小程序类似。今天就先记录一下vue的开发运行搭建。所需工具如下 nod…...

Python | 为FastAPI后端服务添加API Key认证(分别基于路径传参和header两种方式且swagger文档友好支持)

文章目录 01 前言02 路径传参方式添加API Key2.1 完整代码2.2 请求示例2.3 swagger文档测试 03 请求头Header方式传入API Key&#xff08;推荐&#xff09;3.1 完整代码3.2 请求示例3.3 swagger文档测试 01 前言 FastAPI&#xff0c;如其名所示&#xff0c;是一个极为高效的框…...

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&#xff0c;现更新为 点击build -》 build bundle -》build apk&#xff0c;项目报 Could not determine the dependencies of task :app:compileDebugUnitTestJavaWithJavac. > Could not resolve all task dependencies for configur…...

【慕伏白教程】 Linux 深度学习服务器配置指北

文章目录 镜像烧录系统安装系统配置常用包安装 镜像烧录 下载 Ubuntu 镜像 Ubuntu 桌面版 下载烧录工具 balenaEtcher 准备至少 8G 的 空白U盘 开始烧录 系统安装 开机进入BIOS&#xff0c;修改U盘为第一启动 选择 Try or Install Ubuntu 往下拉&#xff0c;选择 中文&a…...

学习windows系统让python脚本在后台运行的方法

学习windows系统让python脚本在后台运行的方法 windows 后台运行并输出日志文件windows 前台运行并输出日志文件 windows 后台运行并输出日志文件 命令&#xff1a; python qipa250.py >> qipa250_logs.log 2>&1 &窗口关闭后程序也就关闭了 windows 前台运…...

华为OD机试 - 第k个排列 - 全排列递归(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…...

流媒体播放器EasyPlayer.js无法播放H.265的情况是什么原因?该如何解决?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#…...

负载均衡器监控

什么是负载均衡器 负载均衡建立在现有网络结构之上&#xff0c;它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其意思就是分摊到多个操作单元上进行执行&#xff0c;例如Web服务器、FTP服务器、企…...

【计算机视觉】2.图像特征提取

图像特征提取 一、颜色特征量化颜色直方图聚类颜色直方图 二、边缘特征边缘边缘定义边缘提取边缘精细 三、特征点的特征描述子Harris角点FAST角点斑点SIFTHaar-like特征SURFORBLBPGabor 一、颜色特征 量化颜色直方图 HSV空间 优势&#xff1a;计算高效 劣势&#xff1a;量化问…...

华为存储培训

01 存储前沿技术和发展趋势 狭义的存储定义 CD、DVD、ZIP、磁带、硬盘等 广义的存储定义 存储硬件系统&#xff08;磁盘阵列&#xff0c;控制器&#xff0c;磁盘柜&#xff0c;磁带库等&#xff09; 存储软件&#xff08;备份软件&#xff1b;管理软件&#xff0c;快照&…...

I帧、P帧,B帧,GOP

doGetNextFrame() 在Live555库的FramedSource类中&#xff0c;数据帧的获取位置由doGetNextFrame()函数来设置。这个函数是一个虚函数&#xff0c;子类可以重写它以实现特定类型的数据帧获取逻辑。 在FramedSource的子类中&#xff0c;你可以重写doGetNextFrame()函数&#x…...

Apache DolphinScheduler在中国信通院“2023 OSCAR开源尖峰案例”评选中荣获「尖峰开源项目奖」!

在近日由中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;和中国通信标准化协会联合主办的“2023 OSCAR 开源产业大会”上&#xff0c;主办方公布了 2023 年“OSCAR 开源尖峰案例”评选结果&#xff0c;包括“开源人物”“开源项目”“开源社区”“开源企业”…...

Java Lambda 表达式

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Java Lambda 表达式 Java Lambda 表达式是 Java 8 引入的一种函数式编程特性&#xff0c;它是一种轻量级的匿名函数&#xff0c;允许我们将函数作为方法的参数进行传递…...

数据结构--插入排序

目录 插入排序 算法实现 算法效率分析 插入排序的优化-折半插入排序 最终的结果&#xff1a;&#xff08;方式&#xff09; 优化-折半查找的代码实现 ​回顾 插入排序 算法实现 算法效率分析 空间复杂度和问题规模无关 插入排序的优化-折半插入排序 之前的元素有序&am…...

服务器搭建(TCP套接字)-epoll版(服务端)

epoll 是一种在 Linux 系统上用于高效事件驱动编程的 I/O 多路复用机制。它相比于传统的 select 和 poll 函数具有更好的性能和扩展性。 epoll 的主要特点和原理&#xff1a; 1、事件驱动&#xff1a;epoll 是基于事件驱动的模型&#xff0c;它通过监听事件来触发相应的回调函…...

第一章:最新版零基础学习 PYTHON 教程(第十八节 - Python 表达式语句–Python 中的中断、继续和传递)

在 Python 中使用循环可以高效地自动执行和重复任务。但有时,可能会出现您想要完全退出循环、跳过迭代或忽略该条件的情况。这些可以通过循环控制语句来完成。循环控制语句改变其正常顺序的执行。当执行离开作用域时,在该作用域中创建的所有自动对象都将被销毁。Python支持以…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...