总结一下常见的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(如 HSSFXSSF)在处理 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 字段(StringDate)自动转换

@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 的字段参与读写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/76022.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01-Redis-基础

1 redis诞生历程 redis的作者笔名叫做antirez&#xff0c;2008年的时候他做了一个记录网站访问情况的系统&#xff0c;比如每天有多少个用户&#xff0c;多少个页面被浏览&#xff0c;访客的IP、操作系统、浏览器、使用的搜索关键词等等(跟百度统计、CNZZ功能一样)。最开始存储…

在 Ubuntu 上离线安装 Prometheus 和 Grafana

在 Ubuntu 上离线安装 Prometheus 和 Grafana 的步骤如下: 一.安装验证 二.安装步骤 1.准备离线安装包 在一台可以访问互联网的机器上下载 Prometheus 和 Grafana 的二进制文件。 Prometheus 下载地址:Prometheus 官方下载页面Grafana 下载地址:Grafana 官方下载页面下载所…

mapbox基础,加载ESRI OpenStreetMap开放街景标准风格矢量图

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.1 ☘️mapboxgl.Map style属性二、🍀加载ESRI OpenStreetMap开放街景标准风…

Java 集合有序性与重复性总结及记忆技巧

Java 集合有序性与重复性总结及记忆技巧 一、集合分类速查表 集合类型是否有序是否允许重复记忆口诀ArrayList✅ 有序&#xff08;插入顺序&#xff09;✅ 可重复"数组列表&#xff0c;顺序记牢"LinkedList✅ 有序&#xff08;插入顺序&#xff09;✅ 可重复"…

记录学习的第二十三天

老样子&#xff0c;每日一题开胃。 我一开始还想着暴力解一下试试呢&#xff0c;结果不太行&#x1f602; 接着两道动态规划。 这道题我本来是想用最长递增子序列来做的&#xff0c;不过实在是太麻烦了&#xff0c;实在做不下去了。 然后看了题解&#xff0c;发现可以倒着数。 …

MTK-Android12-13 屏幕永不休眠功能实现

MTK-Android12-13 屏幕永不休眠功能实现 文章目录 需求场景参考资料修改文件简要分析实现方案默认休眠时间设置 def_screen_off_timeout息屏时间添加永不休眠 screen_timeout_entries更新休眠时间 updateUserActivitySummaryLocked 总结 需求 屏幕永不休眠功能 备注&#xff…

Lua 中,`math.random` 的详细用法

在 Lua 中&#xff0c;math.random 是用于生成伪随机数的核心函数。以下是其详细用法、注意事项及常见问题的解决方案&#xff1a; Lua 中&#xff0c;math.random 的详细用法—目录 一、基础用法1. 生成随机浮点数&#xff08;0 ≤ x < 1&#xff09;2. 生成指定范围的随机…

HOW - React Error Catch 机制

目录 1. 错误边界&#xff08;Error Boundaries&#xff09;使用场景写法&#xff08;类组件方式&#xff09;&#xff1a;componentDidCatch 2. 事件处理器中的错误3. 异步函数中的错误&#xff08;如 fetch、Promise&#xff09;4. 全局未捕获错误&#xff08;适用于整个 Rea…

1.ElasticSearch-入门基础操作

一、介绍 The Elastic Stack 包含ElasticSearch、Kibana、Beats、LogStash 这就是所说的ELK 能够安全可靠地获取任何来源、任何格式的数据&#xff0c;然后实时地对数据进行搜索、分析和可视化。Elaticsearch,简称为ES&#xff0c;ES是一个开源的高扩展的分布式全文搜索引擎,是…

通过扣子平台将数据写入飞书多维表格

目录 1.1 创建飞书开放平台应用 1.2 创建飞书多维表格 1.3 创建扣子平台插件 1.1 创建飞书开放平台应用 1.1.1 打开地址&#xff1a;飞书开放平台&#xff0c;点击创建应用 注&#xff1a;商店应用需要申请ISV资质&#xff0c;填写企业主体信息&#xff0c;个人的话&#x…

MYSQL数据库语法补充

一&#xff0c;DQL基础查询 DQL&#xff08;Data Query Language&#xff09;数据查询语言&#xff0c;可以单表查询&#xff0c;也可以多表查询 语法&#xff1a; select 查询结果 from 表名 where 条件&#xff1b; 特点&#xff1a; 查询结果可以是&#xff1a;表中的字段…

Redis到底能不能做主数据库?

张三拍案而起&#xff1a;“Redis 是缓存数据库&#xff0c;怎么能当主数据库用&#xff1f;简直是天方夜谭&#xff01;” 李四冷笑回应&#xff1a;“你没用过&#xff0c;凭什么说不行&#xff1f;我已经用 Redis 做主数据库好几年了&#xff0c;系统稳定得像铁板一块&…

flutter 项目结构目录以及pubspec.ymal等文件描述

在Flutter项目中&#xff0c;目录结构和pubspec.yaml文件是非常重要的组成部分&#xff0c;它们定义了项目的结构、依赖管理以及如何构建和运行项目。下面我将详细解释这些关键元素&#xff1a; 1. Flutter项目目录结构 Flutter项目的标准目录结构通常如下所示&#xff1a; …

CentOS 环境下 MySQL 数据库全部备份的操作指南

最近阿里云个人服务到期&#xff0c;因为是很久之前买的测试机器&#xff0c;配置较低&#xff0c;上面运行的有技术博客 和以往的测试项目&#xff0c;所以准备放弃掉。 需要备份下上面的表结构和数据、以及代码仓库。 下面是一个完整的 CentOS 环境下 MySQL 数据库全部备份…

ecplise 工具 没有Java EE Tools 选项

Java EE Tools 是将项目转换为web项目的重要的快捷键&#xff0c;如果进行web开发 那是不可或缺的 该工具是一个插件&#xff0c;可以作为插件安装到ecplise上 安装步骤如下&#xff1a; 找到help-->install new software 在弹出的页面中 work with中输入&#xff1a;Jun…

544 eff.c 1761 优化设计文档

1:性能分析 1.1性能对比 oneapi 与hygonGcc性能对比发现&#xff0c;544课题中的eff.c 1761循环处&#xff0c;oneapi 进行了循环向量化, gcc使用标量&#xff0c;循环源码前加 #pragma clang loop vectorize(disable) 找出oneapi在该循环处关闭和开启loop vect 的性能差距&a…

LeetCode.3396.使数组元素互不相同所需的最少操作次数

3396. 使数组元素互不相同所需的最少操作次数 给你一个整数数组 nums&#xff0c;你需要确保数组中的元素 互不相同 。为此&#xff0c;你可以执行以下操作任意次&#xff1a; 从数组的开头移除 3 个元素。如果数组中元素少于 3 个&#xff0c;则移除所有剩余元素。 注意&…

【已完结STM32】--自学江协科技笔记汇总

以下学习笔记代码均来自b站江协科技视频 笔记汇总完结 文章笔记对应江科大视频新建工程【2-2】新建工程江科大STM32-GPIO输出 点亮LED&#xff0c;LED闪烁&#xff0c;LED流水灯&#xff0c;蜂鸣器&#xff08;学习笔记&#xff09;_unit32-t rcc-apb2periph-CSDN博客 【3-1】…

QML Loader:加载组件与状态监控

目录 引言相关阅读工程结构示例一&#xff1a;从文件加载组件 (LoaderFile.qml)代码实现被加载的组件&#xff1a;MyComponent.qml代码解析运行效果 示例二&#xff1a;直接加载Component对象 (LoaderComponent.qml)代码实现代码解析运行效果 示例三&#xff1a;监控加载状态 (…

K8S核心技术点

Pod&#xff0c;Service和Deployment的关系 Pod&#xff1a;Kubernetes 中最小的部署单元&#xff0c;用于运行容器化应用。 Service&#xff1a;提供服务发现和负载均衡&#xff0c;为 Pod 提供稳定的网络端点&#xff0c;ClusterIP&#xff0c;NodePort&#xff0c;LoadBala…