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

Java使用xlsx-streamer和EasyExcel解决读取超大excel文件数据处理方法

前言


      最近有个项目在生产环境做数据导入时,发现开始执行导入任务会出现cpu狂飙的情况。几番定位查找发现是在读取excel的时候导致此问题的发生,因此在通常使用的为POI的普通读取,在遇到大数据量excel,50MB大小或数五十万行的级别的数据容易导致读取时内存溢出或者cpu飙升。需要注意,本文讨论的是针对xlsx格式的excel文件上传。

关于Excel相关技术


        在Java技术生态圈中,可以进行Excel处理的主流技术包括:Apache POI,JXL,Alibaba EasyExcel等。由于JXL只支持Excel2003以下版本,所以不太常见。

Apache POI:基于DOM方式进行解析,将文件直接加载内存,所以速度较快,适合Excel文件数量不大的应用场景
Alibaba EasyExcel:采用逐行读取的解析模式,将每一行的解析结果以观察者模式通知处理(AnalyEventListener),所以比较适合数据体量较大的Excel文件解析。

问题代码


       这种方式POI会把文件的所有内容都加载到内存中,读取大的excel文件时很容易占用大量内存导致oom的发生,全部文件加载如下:

  /*** POI方式读取excel** @param file*/public static void readExcelByPoi(File file) {long start = System.currentTimeMillis();//整个文件都一块载入try (InputStream inp = new FileInputStream(file);Workbook wb = WorkbookFactory.create(inp)) {log.info("==读取excel完毕,耗时:{}毫秒,", System.currentTimeMillis() - start);Sheet sheet = wb.getSheetAt(0);//更新总数System.out.println("读取结束行数:" + sheet.getLastRowNum());} catch (Exception e) {e.printStackTrace();}}

当前引入的poi依赖

        <!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.0</version></dependency>

     读取50MB我本地字段不是很多50万行数据
首先在读取excel文件的断点执行之前的cpu和内存的占用分别为50%和42%,上传的excel大小为50MB,这里我就不一一带大家测试了,以上此种方式肯定是行不通的。

解决方案一:xlsx-streamer


      我们采用分段缓存的方式加载数据到内存中,此种方式在创建Workbook对象时借助xlsx-streamer(StreamingReader) 来创建一个缓冲区域批量地读取文件 ,因此不会将整个文件实例化到对象当中,代码如下:

引入依赖:

        <!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.0</version></dependency><!-- 读取大量excel数据时使用 --><dependency><groupId>com.monitorjbl</groupId><artifactId>xlsx-streamer</artifactId><version>2.1.0</version></dependency>

示例代码:

    /*** 大批量数据读取 十万级以上* 思路:采用分段缓存加载数据,防止出现OOM的情况** @param file* @throws Exception*/public static void readLagerExcel(File file) throws Exception {InputStream inputStream = new FileInputStream(file);long start = System.currentTimeMillis();try (Workbook workbook = StreamingReader.builder().rowCacheSize(10 * 10)  //缓存到内存中的行数,默认是10.bufferSize(1024 * 4)  //读取资源时,缓存到内存的字节大小,默认是1024.open(inputStream)) { //打开资源,可以是InputStream或者是File,注意:只能打开.xlsx格式的文件Sheet sheet = workbook.getSheetAt(0);log.info("==读取excel完毕,耗时:{}毫秒,", System.currentTimeMillis() - start);//遍历所有的行for (Row row : sheet) {System.out.println("开始遍历第" + row.getRowNum() + "行数据:");//遍历所有的列for (Cell cell : row) {System.out.print(cell.getStringCellValue() + " ");}System.out.println(" ");}//总数System.out.println("读取结束行数:" + sheet.getLastRowNum());}}

加载结果


40万级别数据近花费5秒,加载是不是很快了。

百万级别,也就花费7秒

前端也还做了个测试页面如下:

Excel文件上传

解决方案二:EasyExcel

     使用EasyExcel解决大文件Excel内存溢出的问题,基于POI进行封装优化,可以在不考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

官网: https://easyexcel.opensource.alibaba.com/
github:https://github.com/alibaba/easyexcel

引入依赖

        <!--easyExcel工具--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.1</version></dependency>

示例代码


仅做简单读取示例:

 /*** EasyExcel方式读取excel* 读取并封装为对象,ExcelData大家需要的对象* @param file*/public static void readExcelByEasyExcel(File file) {long start = System.currentTimeMillis();List<ExcelData> excelDataList = EasyExcel.read(file).head(ExcelData.class).sheet(0).doReadSync();excelDataList.stream().forEach(x -> System.out.println(x.toString()));log.info("==读取excel完毕,耗时:{}毫秒,", System.currentTimeMillis() - start);}/*** EasyExcel方式读取excel* 不指定head类* @param file*/public static void readExcelByEasyExcel1(File file) {long start = System.currentTimeMillis();List<Map<Integer, String>> listMap = EasyExcel.read(file).sheet(0).doReadSync();listMap.stream().forEach(x -> System.out.println(JSON.toJSONString(x)));log.info("==读取excel完毕,耗时:{}毫秒,", System.currentTimeMillis() - start);}

   得出一个结论就是使用阿里EasyExcel确实方便很多,不仅支持excel,csv也可以。支持的文件类型更多些,但是第一种方式也还可以,毕竟poi我们也一直在使用。

相关文章:

Java使用xlsx-streamer和EasyExcel解决读取超大excel文件数据处理方法

前言 最近有个项目在生产环境做数据导入时&#xff0c;发现开始执行导入任务会出现cpu狂飙的情况。几番定位查找发现是在读取excel的时候导致此问题的发生&#xff0c;因此在通常使用的为POI的普通读取&#xff0c;在遇到大数据量excel&#xff0c;50MB大小或数五十万行的级别的…...

智能驾驶规划控制理论学习04-基于车辆运动学的规划方法

目录 一、线性二自由度汽车模型&#xff08;自行车模型&#xff09; 1、二自由度模型概述 2、不同参考点下的状态空间方程 3、前向仿真 二、运动基元生成方法 1、杜宾斯曲线&#xff08;Dubins Curve&#xff09; 2、Reeds Shepp Curve 三、多项式曲线&#xff08;Poly…...

一键查看:大厂网站都用了啥技术栈,有图有真相。

本次我们采用Wappalyzer插件来看下国内大厂的网站都采用了什么技术架构&#xff0c;文章最后由Wappalyzer的安装方法。 今日头条网站 淘宝网站 哔哩哔哩 京东商城 花瓣网 CSDN 国务院 网易 58同城 腾讯网 如何安装Wappalyzer 用Edge浏览器即可...

C语言-指针(下)

文章目录 前言    文章目录 前言 一、指针运算 1.指针-整数 2.指针-指针 3.指针关系运算 二、野指针 1.概念 2.野指针的成因 1.未初始化 2.指针越界访问 3.指针指向的空间释放 3.避免野指针 1.指针初始化 2.小心指针越界 3. 指针变量不再使用时&#xff0c;及时置NULL 总结 …...

尚硅谷JavaScript高级学习笔记

01 准备 JavaScript中函数是对象。我们后续描述构造函数的内存模型时&#xff0c;会将构造函数称为构造函数对象。 02 数据类型 typeof 运算符来查看值的类型&#xff0c;它返回的是类型的字符串值 会做数据转换 03 相关问题 04数据_变量_内存 05相关问题1 06相关问题2 …...

六、长短时记忆网络语言模型(LSTM)

为了解决深度神经网络中的梯度消失问题&#xff0c;提出了一种特殊的RNN模型——长短期记忆网络&#xff08;Long Short-Term Memory networks, LSTM&#xff09;&#xff0c;能够有效的传递和表达长时间序列中的信息并且不会导致长时间前的有用信息被忽略。 长短时记忆网络原理…...

Filter过滤器+JWT令牌实现登陆验证

一、背景 我们需要在客户端访问服务器的时候给定用户一定的操作权限&#xff0c;比如没有登陆时就不能进行其他操作。如果他需要进行其他操作&#xff0c;而在这之前他没有登陆过&#xff0c;服务端则需要将该请求拦截下来&#xff0c;这就需要用到过滤器&#xff0c;过滤器可以…...

SQL学习十八~十九

...

2024 AI 辅助研发的新纪年

随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅助研发正成为科技界和工业界瞩目的焦点。从医药研发到汽车设计&#xff0c;从软件开发到材料科学&#xff0c;AI正逐渐渗透到研发的各个环节&#xff0c;变革着传统的研发模式。在这一背景下&#xff0c;AI辅助研发不仅…...

【牛客】HJ87 密码强度等级 CM62 井字棋

题目一:密码强度等级 题目链接&#xff1a;密码强度等级_牛客题霸_牛客网 (nowcoder.com) 本题主要考察C语言中逻辑分支语句&#xff0c;基本语句以及对各种特殊字符 &#xff0c;ASCII值以及条件表达中的逻辑运算符关系运算符各自功能的理解&#xff0c;以及基本使用&#x…...

【论文速读】 | DeGPT:通过大语言模型优化反编译器输出

本次分享论文为&#xff1a;DeGPT: Optimizing Decompiler Output with LLM 基本信息 原文作者&#xff1a;Peiwei Hu, Ruigang Liang, Kai Chen 作者单位&#xff1a;中国科学院信息工程研究所&#xff1b;中国科学院大学网络空间安全学院 关键词&#xff1a;反向工程&…...

【DP】蓝桥杯第十三届-费用报销

#include<iostream> #include<algorithm> #include<cstring> #include<set> #include<queue> using namespace std; const int N1010; int dp[N][5010];//dp[i][j]:选到第i个物品是否能取到价值j&#xff1b; int month[13]{0,31,28,31,30,31,30…...

15. C++泛型与符号重载

【泛型编程】 若多组类型不同的数据需要使用相同的代码处理&#xff0c;在C语言中需要编写多组代码分别处理&#xff0c;这样做显然太过繁琐&#xff0c;C增加了虚拟类型&#xff0c;使用虚拟类型可以实现一组代码处理多种类型的数据。 虚拟类型是暂时不确定的数据类型&#…...

老司机都懂的!【打赏】完美运营的最新视频打赏系统

完美运营的最新视频打赏系统优于市面上95%的打赏系统&#xff0c;与其他打赏系统相比&#xff0c;功能更加强大&#xff0c;完美运营且无bug。支付会调、短链接生成、代理后台、价格设置和试看功能等均没有问题。 以上为原简介&#xff0c;经测试验证。成功搭建并可以正常进入…...

JavaWeb笔记 --- 二、Maven

二、Maven Maven概述 所有的IDE创建的Maven项目都可以使用 Maven简介 Maven模型 Maven常用命令 Maven生命周期 Maven坐标 依赖管理 dpendencies&#xff1a;依赖 依赖范围...

【C++】C++11---右值引用和移动语义

目录 1、什么是左值引用和右值引用2、左值引用与右值引用比较3、右值引用使用场景和意义4、右值引用引用左值的分析5、完美转发 1、什么是左值引用和右值引用 传统的C语法中就有引用的语法&#xff0c;而C11中新增了的右值引用语法特性&#xff0c;所以从现在开始我们之前学习…...

消息队列-kafka-消息发送流程(源码跟踪) 与消息可靠性

官方网址 源码&#xff1a;https://kafka.apache.org/downloads 快速开始&#xff1a;https://kafka.apache.org/documentation/#gettingStarted springcloud整合 发送消息流程 主线程&#xff1a;主线程只负责组织消息&#xff0c;如果是同步发送会阻塞&#xff0c;如果是异…...

机器学习笔记 计算机视觉中的测距任务常见技术路线

一、计算机视觉中的测距任务 测距是计算机视觉中的一项关键任务,涉及测量物体和相机之间的距离。这些信息可用于多种应用,包括机器人、自动驾驶汽车和增强现实。测距技术有很多种,包括主动式和被动式,每种技术都有自己的优点和局限性。主动测距技术,例如飞行时间、结构光和…...

云计算 3月8号 (wordpress的搭建)

项目wordpress 实验目的&#xff1a; 熟悉yum和编译安装操作 锻炼关联性思维&#xff0c;便于以后做项目 nginx 编译安装 1、安装源码包 [rootlinux-server ~]# yum -y install gcc make zlib-devel pcre pcre-devel openssl-devel [rootlinux-server ~]# wget http://nginx.…...

【CSS】(浮动定位)易忘知识点汇总

浮动特性 加了浮动之后的元素,会具有很多特性,需要我们掌握的. 1、浮动元素会脱离标准流(脱标&#xff1a;浮动的盒子不再保留原先的位置) 2、浮动的元素会一行内显示并且元素顶部对齐 注意&#xff1a; 浮动的元素是互相贴靠在一起的&#xff08;不会有缝隙&#xff09;&…...

终极窗口控制指南:如何用WindowResizer轻松管理任意窗口尺寸

终极窗口控制指南&#xff1a;如何用WindowResizer轻松管理任意窗口尺寸 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 还在为那些无法调整大小的Windows应用程序窗口而烦恼吗&am…...

别再只会用轮询了!GD32F103 USART中断与DMA传输实战对比(附代码)

GD32F103 USART通信三剑客&#xff1a;轮询、中断与DMA的实战抉择 在嵌入式开发中&#xff0c;串口通信就像空气一样无处不在——调试信息输出、传感器数据采集、设备间通信都离不开它。但很多开发者停留在最基础的轮询方式&#xff0c;就像只会用螺丝刀却面对一整套精密工具。…...

解锁C语言中的多返回值技巧

在C语言编程中,常常会遇到需要从函数中返回多个值的情况。虽然C语言不直接支持多返回值,但我们可以通过一些技巧来实现这一目的。本文将详细探讨如何在C语言中返回多个值,并通过实例说明。 一、背景介绍 在C语言中,函数默认只能返回一个值。这对于需要处理多个结果的情况…...

利用重力势能为电子表供电的创新设计

1. 项目背景与设计初衷作为一名电子设备爱好者&#xff0c;我多年来一直使用Casio F91W这款经典数字手表。它的可靠性毋庸置疑&#xff0c;但每次更换CR2016纽扣电池时&#xff0c;总让我感到一丝不安。这种一次性锂电池虽然单颗仅含36毫克锂&#xff0c;但考虑到全球数以亿计的…...

D3KeyHelper终极指南:5分钟上手暗黑3最强按键宏工具

D3KeyHelper终极指南&#xff1a;5分钟上手暗黑3最强按键宏工具 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面&#xff0c;可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑3中频繁的技能操作而手指酸…...

WeChatExporter:你的微信记忆守护者,一键解锁被封存的聊天时光

WeChatExporter&#xff1a;你的微信记忆守护者&#xff0c;一键解锁被封存的聊天时光 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 还记得那些深夜的长谈吗&#xff1…...

Mac新手必看:从bash切换到zsh后,Maven、Brew命令失效的保姆级修复指南

Mac开发者必备&#xff1a;zsh环境变量迁移全攻略与效率提升指南 刚把Mac的默认shell从bash切换到zsh时&#xff0c;那种"昨天还能用的命令今天全报错"的恐慌感我至今记忆犹新。Maven构建失败、brew命令失踪&#xff0c;连最基本的工具都集体罢工——这其实是每个Mac…...

华为OD机试真题 新系统 2026-04-19 JavaGo 实现【8位LED控制器】

目录 题目 思路 Code 题目 有一个8位LED控制器,包含8个LED灯(编号0-7),初始状态全灭,用8位二进制表示为:00000000。控制器可以接收以下三种指令: Lx:L表示点亮操作,x表示LED的编号(0一7),操作得到的结果是:点亮第x个LED灯,把状态设为1。 Dx:D表示熄灭操作,x表示LED的…...

从 CMS 到 ZGC,JVM 是如何将停顿时间压缩到 1 毫秒的?

要理解 GC 的演进&#xff0c;我们打个极度通俗的比方&#xff1a;JVM 的堆内存就是一家正在营业的“疯狂大餐厅”&#xff0c;里面挤满了客人&#xff08;活着的对象&#xff09;&#xff0c;同时也满地都是别人吃剩的骨头和纸巾&#xff08;死掉的垃圾对象&#xff09;。 垃圾…...

nli-MiniLM2-L6-H768效果展示:英文文本对蕴含关系打分真实案例集

nli-MiniLM2-L6-H768效果展示&#xff1a;英文文本对蕴含关系打分真实案例集 1. 模型核心能力概览 nli-MiniLM2-L6-H768是一个轻量级自然语言推理模型&#xff0c;专门用于判断两段文本之间的逻辑关系。与生成式模型不同&#xff0c;它的核心能力是给文本对打分&#xff0c;判…...