总结一下常见的EasyExcel面试题
说一下你了解的POI和EasyExcel
POI(Poor Obfuscation Implementation):它是 Apache 软件基金会的一个开源项目,为 Java 程序提供了读写 Microsoft Office 格式文件的功能,支持如 Excel、Word、PowerPoint 等多种文件格式,是 Java 操作 Office 文档的基础工具,发展历史悠久,功能强大且全面
EasyExcel:是阿里巴巴开源的一个基于 POI 进行二次封装的轻量级 Excel 处理框架,主要专注于 Excel 文件的读写操作,简化了 POI 的操作流程
EasyExcel对比POI
功能丰富度
POI:POI 是一个底层的 Java 操作 Excel 的工具包,在进行读写操作时,需要手动处理文件流、解析器、工作表、行和单元格等多个元素
以读取文件为例,需要创建工作簿对象、获取工作表、遍历行和单元格等,代码量较多且逻辑复杂。
对于复杂的操作,如设置单元格样式、合并单元格等,还需要编写更多的代码来实现。这使得使用 POI 进行开发时,代码的复杂度显著增加
EasyExcel:
EasyExcel 对常见的 Excel 读写场景进行了高度封装,提供了极为简洁的 API。在读取 Excel 时,只需定义与表格列对应的实体类和监听器
内存占用
EasyExcel 采用基于事件驱动的读写模式,在读写大数据量的 Excel 文件时,逐行处理数据,不需要将整个文件加载到内存中。这使得它在处理大规模数据时,内存占用非常低,能够有效避免内存溢出的问题。即使处理包含数百万行数据的 Excel 文件,也能稳定运行
POI 的用户模型 API(如 HSSF 和 XSSF)在处理 Excel 文件时,会将整个文件加载到内存中,当文件数据量较大时,会占用大量的内存资源,容易导致内存溢出。虽然 POI 也提供了事件模型 API(如 SAX 解析器)来处理大数据量文件,但使用起来相对复杂,需要开发人员具备较高的技术水平
读写性能
POI:POI 的用户模型 API 在处理大数据量文件时,由于需要将整个文件加载到内存中,会导致读写效率降低。而事件模型 API 虽然在处理大数据量时性能较好,但需要手动处理事件,开发难度较大,并且在处理一些复杂操作时,效率也会受到一定影响
EasyExcel:由于采用了事件驱动的方式,EasyExcel 在读写数据时,数据处理和文件操作是同步进行的,减少了中间环节,提高了读写效率。特别是在处理大数据量文件时,其逐行处理的方式能够更快地完成读写操作
在处理大数据量的 Excel 文件时,EasyExcel 采用了基于事件驱动的读写模式,逐行处理数据,避免了将整个文件加载到内存中,从而大大降低了内存占用。例如,当需要读取一个包含数百万行数据的 Excel 文件时,使用 POI 的用户模型 API 可能会导致内存溢出,而 EasyExcel 可以稳定地处理这些数据
事件驱动为什么快+安全?
EasyExcel 通过 SAX 事件驱动 + 流式读写,实现了:
✅ 超低内存占用(恒定内存,与文件大小无关)。
✅ 高效处理大文件(GB 级 Excel 轻松应对)。
✅ 避免 OOM(彻底解决 POI 的内存瓶颈)
为什么说EasyExcel的OOM风险小
EasyExcel不需要将整个文件加载到内存中,poi需要加载整个文件?
1. 传统 POI 的 DOM 模式:全量加载
DOM(Document Object Model):
POI 将整个 Excel 文件解析为一个树形结构对象,全部加载到内存中。
类似于把一本书全部复印到脑子里,再逐页阅读
2. EasyExcel 的 SAX 模式:流式逐行处理
SAX(Simple API for XML):
EasyExcel 像流水线一样逐行扫描 Excel 文件,触发事件回调处理数据。
类似于用扫描仪逐页扫描一本书,读一页处理一页,然后立刻扔掉
EasyExcel 的 SAX 模式 通过事件驱动 + 即时丢弃数据(即时刷盘),实现了按需加载,而 POI 的 DOM 模式 为支持复杂功能必须全量加载
EasyExcel如何避免写入OOM?
POI必须是全量写入,这也是它的内存瓶颈
而EasyExcel 默认每处理 2000 行(可配置)就将数据从内存刷入磁盘文件流,即时释放内存。
内存占用 ≈ 单批次数据大小(而非全量数据)。例如写入sheet1然后释放sheet1,再写入sheet2,而不用sheet1,sheet2必须一起写入,分sheet页写可以实现资源及时释放
EasyExcel为啥不维护了?对此你怎么看?
核心功能已成熟,暂无重大特性新增需求。以修复 Bug 和兼容性更新为主,而非频繁发布新功能
开发者资源转移,阿里内部可能将资源投入其他更高优先级项目(如 Spring Cloud Alibaba),开源团队依赖社区贡献,但核心开发者时间有限
面试回答思路引导
面试回答
poi是apache的开源项目,功能非常丰富,而EasyExcel是基于poi的二次简化封装,简化了poi的操作,方便使用
主要让写入和写出更加简单,没必要去操作很多的细节,例如不需要手动编写输入输出流,手动关闭输入输入流的资源,编写解析器等
EasyExcel只需要只需定义与表格列对应的实体类和监听器
EasyExcel主要解决的poi的内存瓶颈和读取效率问题
poi使用的是传统的全量加载,而EasyExcel是流失加载,也就是事件驱动+及时刷盘
poi读取的时候,必须要把整个文件加载到内存中读取
poi写入的时候必须一次性全量写入
而EasyExcel读取的时候是流式读取,逐行扫描,读取完的数据从内存中扔掉,不占用内存
EasyExcel写入的时候是流式写入,我们分sheet页写入,这个sheet页写入完就及时释放资源,实现及时刷盘不占用内存
这是他们的区别,也是基于poi的重点优化,poi因为是全量读取和写入逻辑所以oom的概率会非常大
EasyExcel是写完sheet页就释放不会一直占用内存,所以oom的概率小,但这并不说明不会出现oom问题了,使用EasyExcel的时候还是需要严格控制sheet页的,因为sheet页是存到一个List<>中的,如果sheet页过大仍然会导致oom问题
常用的方法
EasyExcel.read() 读
EasyExcel.write() 写
WriteSheet sheet = EasyExcel.writerSheet("批次").build() 构造sheet页
ExcelWriter writer = EasyExcel.write(filePath).build() 构造用来写入的ExcelWriter
writer.write(excels, sheet) 把Sheet页放到ExcelWriter里面,然后写入我们传入的内容excels列表
@Testvoid allData(){List<Excel> excels = excelMapper.selectAllOrderById();String filePath = "C:\\Users\\ziJian.zheng\\IdeaProjects\\Kira-Test\\src\\main\\resources\\templates\\test.xlsx";WriteSheet sheet = EasyExcel.writerSheet("批次" ).build();//用来写入的ExcelWriterExcelWriter writer = EasyExcel.write(filePath).build();writer.write(excels, sheet);}
常见的注解
@ExcelProperty(value = "用户姓名",index = 0)
效果:index属性可以指定当前字段对应excel中的哪一列,可以根据列名value去匹配,也可以不写
如果不使用@ExcelProperty注解,成员变量从上到下的顺序,对应表格中从左到右的顺序
@ExcelIgnore
读写的时候会忽略该字段
@DateTimeFormat 日期转换
日期格式转换:将 Excel 中的日期格式数据(如 2023-01-01)与 Java 字段(String 或 Date)自动转换
@DateTimeFormat("yyyy-MM-dd") // 格式化为"2023-01-01"
private String createDate;
@NumberFormat 数字格式转换
将 Excel 中的数字(如 1,000.50)与 Java 字段(String 或数值类型)自动转换
@NumberFormat("#,##0.00") // 格式化为"1,000.50"
private String price;
@ExcelIgnoreUnannotated
制类字段的默认行为:标注在类上,决定未加 @ExcelProperty 的字段是否参与读写。
不标注该注解:所有字段(无论是否有 @ExcelProperty)都会参与读写。
标注该注解:只有显式标注 @ExcelProperty 的字段参与读写
相关文章:
总结一下常见的EasyExcel面试题
说一下你了解的POI和EasyExcel POI(Poor Obfuscation Implementation):它是 Apache 软件基金会的一个开源项目,为 Java 程序提供了读写 Microsoft Office 格式文件的功能,支持如 Excel、Word、PowerPoint 等多种文件格…...
【JAVA】十、基础知识“类和对象”干货分享~(三)
目录 1. 封装 1.1 封装的概念 1.2 访问限定符 public(公开访问) private(私有访问) 1.3 包 1.3.1 包的概念 1.3.2 导入包中的类 1.3.3 自定义包 2. static成员 2.1 static变量(类变量) 2.1.1 sta…...
DeepSeek+SpringAI家庭AI医生
文章目录 项目架构项目开发内容项目用户用例图项目地址开发环境大模型使用本地:Ollama部署DeepSeek离线与在线api大模型客户端使用 数据库脚本代码deepseek创建定制医生模型 内网互通原则云服务器类型 项目架构 项目开发内容 项目用户用例图 项目地址 FamilyAIDoct…...
PyTorch:解锁AI新时代的钥匙
(前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站)。 揭开PyTorch面纱 对于许多刚开始接触人工智能领域的朋友来说,PyTorch这个名字或许既熟悉又陌生。…...
C++第14届蓝桥杯b组学习笔记
1. 日期统计 小蓝现在有一个长度为 100100 的数组,数组中的每个元素的值都在 00 到 99 的范围之内。数组中的元素从左至右如下所示: 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4…...
解锁工业通信:Profibus DP到ModbusTCP网关指南!
解锁工业通信:Profibus DP到ModbusTCP网关指南! 在工业自动化领域,随着技术的不断进步和应用场景的日益复杂,不同设备和系统之间的通讯协议兼容性问题成为了工程师们面临的一大挑战。尤其是在Profibus DP和Modbus/TCP这两种广泛应…...
每日一题(小白)字符串娱乐篇16
分析题意可以了解到本题要求在一串字符串中找到所有组合起来排序递增的字符串。我们可以默认所有字符在字符串中的上升序列是1,从第一个字符开始找,如果后面的字符大于前面的字符就说明这是一个上序列那么后面字符所在的数组加一,如果连接不上…...
面试算法高频01
题目描述 验证回文串 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 示例 1: 输入: "A man, a plan, a canal: Panama" 输出: true示例 2: 输入: "race a car" 输出: falseimport…...
如何深刻理解Reactor和Proactor
前言: 网络框架的设计离不开 I/O 线程模型,线程模型的优劣直接决定了系统的吞吐量、可扩展性、安全性等。目前主流的网络框架,在网络 IO 处理层面几乎都采用了I/O 多路复用方案(又以epoll为主),这是服务端应对高并发的性能利器。 …...
java基础 数组Array的介绍
Array 数组定义一维数组多维数组动态数组常见方法Arrays排序1.sort() 排序 2.parallelSort() 排序 查找:binarySearch()填充:fill()比较:equals() 和 deepEquals()复制:copyOf() 和 copyOfRange()转换为列表:asList()转…...
Elixir语言的函数定义
Elixir语言的函数定义 Elixir是一种基于Erlang虚拟机(BEAM)的函数式编程语言,因其并发特性及可扩展性而受到广泛欢迎。在Elixir中,函数是程序的基本构建块,了解如何定义和使用函数对于掌握这门语言至关重要。本文将深…...
我的NISP二级之路-02
目录 一.数据库 二.TCP/IP协议 分层结构 三.STRIDE模型 四.检查评估与自评估 检查评估 自评估 五.信息安全应急响应过程 六.系统工程 七.SSE-CMM 八.CC标准 九.九项重点工作 记背: 一.数据库 关于数据库恢复技术,下列说法不正确的是:…...
k8s1.24升级1.28
0、简介 这里只用3台服务器来做一个简单的集群,当前版本是1.24.17目标升级到1.28.17 地址主机名192.168.160.40kuber-master-1192.168.160.41kuber-master-2192.168.160.42kuber-node-1 因为1.24已经更换过了容器运行时,所以之后的升级相对就会简单&am…...
常见的微信个人号二次开发功能
一、常见开发功能 1. 好友管理 好友列表维护 添加/删除好友 修改好友信息(备注、标签等) 分组管理 创建/编辑/删除标签 好友分类与筛选 2. 消息管理 信息发送 支持多类型内容:文本、图片、视频、文件、小程序、名片、URL链接等 附加功…...
unity的dots中instantiate克隆对象后,对象会在原位置闪现的原因和解决
原因 在Entity中有两个位置信息,一个是local transform。一个是local to world 其中local transform负责具体位置,local to world 负责渲染位置,即图像的渲染的位置是根据local to world的。 local to world 的更新是引擎自己控制的&#x…...
去中心化固定利率协议
核心机制与分类 协议类型: 借贷协议(如Yield、Notional):通过零息债券模型(如fyDai、fCash)锁定固定利率。 收益聚合器(如Saffron、BarnBridge):通过风险分级或博弈论…...
Java面试黄金宝典31
1. 什么是封锁协议 定义:封锁协议是在运用封锁机制时,为了保证事务的一致性和隔离性,对何时申请封锁、持锁时间以及何时释放封锁等问题制定的规则。它可防止并发操作引发的数据不一致问题,如丢失修改、不可重复读和读 “脏” 数据…...
R语言——绘制生命曲线图(细胞因子IL5)
绘制生命曲线图(根据细胞因子) 说明流程代码加载包读取Excel文件清理数据重命名列名处理IL-5中的"<"符号 - 替换为检测下限的一半首先找出所有包含"<"的值检查缺失移除缺失值根据IL-5中位数将患者分为高低两组 创建生存对象拟…...
在内网环境中为 Gogs 配置 HTTPS 访问
在内网环境中为 Gogs 配置 HTTPS 访问,虽然不需要公网域名,但仍需通过自签名证书或私有证书实现加密。以下是详细步骤和方案: 一、核心方案选择 方案适用场景优点缺点自签名证书快速测试、临时使用无需域名,快速生成浏览器提示“…...
神马系统8.5搭建过程,附源码数据库
项目介绍 神马系统是多年来流行的一款电视端应用,历经多年的发展,在稳定性和易用性方面都比较友好。 十多年前当家里的第一台智能电视买回家,就泡在某论坛,找了很多APP安装在电视上,其中这个神马系统就是用得很久的一…...
大模型论文:Improving Language Understanding by Generative Pre-Training
大模型论文:Improving Language Understanding by Generative Pre-Training OpenAI2018 文章地址:https://www.mikecaptain.com/resources/pdf/GPT-1.pdf 摘要 自然语言理解包括各种各样的任务,如文本蕴涵、问题回答、语义相似性评估和文…...
SDL视频显示函数
文章目录 1. **`SDL_Init()`**2. **`SDL_CreateWindow()`**3. **`SDL_CreateRenderer()`**4. **`SDL_CreateTexture()`**5. **`SDL_UpdateTexture()`**6. **`SDL_RenderCopy()`**7. **`SDL_RenderPresent()`**8. **`SDL_Delay()`**9. **`SDL_Quit()`**总结示例代码:代码说明:…...
[ctfshow web入门] web18
前置知识 js(javascript)语言用于前台控制,不需要知道他的语法是什么,以高级语言的阅读方式也能看懂个大概。 在JavaScript中,confirm()是一个用于显示确认对话框的内置函数,不用知道怎么使用。 信息收集 提示:不要…...
基于 docker 的 Xinference 全流程部署指南
Xorbits Inference (Xinference) 是一个开源平台,用于简化各种 AI 模型的运行和集成。借助 Xinference,您可以使用任何开源 LLM、嵌入模型和多模态模型在云端或本地环境中运行推理,并创建强大的 AI 应用。 一、下载代码 请在控制台下面执行…...
Vue组件化开发深度解析:Element UI与Ant Design Vue对比实践
一、Vue组件化开发的核心优势 1.1 组件化架构的天然优势 Vue的组件系统是其最核心的特性之一,采用单文件组件(.vue)形式,将HTML、CSS和JavaScript组合在同一个文件中,形成高内聚、低耦合的代码单元。这种设计显著提升…...
SQL Server查询性能下降:执行计划不稳定与索引优化
问题现象: SQL Server 2022 中某些关键查询性能突然下降,执行时间从毫秒级增至数秒,日志中未报错,但查询计划显示低效的索引扫描或键查找。 快速诊断 捕获实际执行计划: -- 启用实际执行计划 SET STATISTICS XML, TIME…...
【学Rust写CAD】31 muldiv255函数(muldiv255.rs,已经取消)
源码 // Calculates floor(a*b/255 0.5) #[inline] pub fn muldiv255(a: u32, b: u32) -> u32 {// The deriviation for this formula can be// found in "Three Wrongs Make a Right" by Jim Blinn.let tmp a * b 128;(tmp (tmp >> 8)) >> 8 }代…...
`uia.WindowControl` 是什么:获取窗口文字是基于系统的 UI 自动化接口,而非 OCR 方式
uia.WindowControl 是什么:获取窗口文字是基于系统的 UI 自动化接口,而非 OCR 方式 uia.WindowControl 通常是基于 Windows 系统的 UI 自动化框架(如 pywinauto 中的 uia 模块)里用于表示窗口控件的类。在 Windows 操作系统中,每个应用程序的窗口都可以看作是一个控件,ui…...
vue3 处理文字 根据文字单独添加class
下面写的是根据后端返回的html 提取我需要的标签和字 将他们单独添加样式 后端返回的数据 大概类似于<h1>2024年“双11”购物节网络零售监测报告</h1><p>表1 “双11” 期间网络零售热销品类TOP10</p> function checkfun(newList){if (newList) {let …...
Python爬虫教程011:scrapy爬取当当网数据开启多条管道下载及下载多页数据
文章目录 3.6.4 开启多条管道下载3.6.5 下载多页数据3.6.6 完整项目下载3.6.4 开启多条管道下载 在pipelines.py中新建管道类(用来下载图书封面图片): # 多条管道开启 # 要在settings.py中开启管道 class DangdangDownloadPipeline:def process_item(self, item, spider):…...
