news 2026/4/17 11:57:31

Java 读取 Excel 文件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 读取 Excel 文件

Java 读取 Excel 文件

      • 一、前置准备:引入依赖
        • 方案 1:Apache POI(功能全,兼容所有Excel版本)
        • 方案 2:EasyExcel(阿里开源,低内存,推荐大数据量)
      • 二、方案 1:Apache POI 读取 Excel(通用场景)
        • 场景 1:读取所有sheet的所有单元格(基础版)
        • 场景 2:读取指定sheet和指定行(精准读取)
      • 三、方案 2:EasyExcel 读取 Excel(高性能,推荐大数据量)
        • 步骤 1:定义数据实体(与Excel表头映射)
        • 步骤 2:自定义监听器(处理读取到的数据)
        • 步骤 3:读取Excel文件(核心代码)
      • 四、关键注意事项
        • 1. 文件路径与权限
        • 2. 版本兼容
        • 3. 性能优化
        • 4. 日期/数字格式
      • 五、两种方案对比
      • 六、常见问题解决
        • 1. `FileNotFoundException`
        • 2. 内存溢出(OOM)
        • 3. 日期读取为数字

Java 读取 Excel 文件核心依赖Apache POI(兼容.xls(Excel 97-2003)和.xlsx(Excel 2007+))或EasyExcel(阿里开源,低内存、高性能),以下是两种主流方案的完整实现,覆盖「读取简单单元格、读取指定sheet、读取表头+数据」等场景。

一、前置准备:引入依赖

方案 1:Apache POI(功能全,兼容所有Excel版本)

Maven 依赖(需同时引入poipoi-ooxml,分别对应.xls.xlsx):

<dependencies><!-- 核心依赖:处理 .xls --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.5</version><!-- 推荐最新稳定版 --></dependency><!-- 处理 .xlsx --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.5</version></dependency><!-- 可选:简化日期格式处理 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version></dependency></dependencies>
方案 2:EasyExcel(阿里开源,低内存,推荐大数据量)

Maven 依赖(仅需核心包,自动兼容.xls/.xlsx):

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version><!-- 最新版 --></dependency><!-- 可选:日志依赖(EasyExcel 依赖 slf4j) --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.9</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>2.0.9</version></dependency>

二、方案 1:Apache POI 读取 Excel(通用场景)

场景 1:读取所有sheet的所有单元格(基础版)
importorg.apache.poi.ss.usermodel.*;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;importorg.apache.poi.hssf.usermodel.HSSFWorkbook;importjava.io.FileInputStream;importjava.io.IOException;publicclassPOIExcelReader{publicstaticvoidmain(String[]args){StringfilePath="D:/test.xlsx";// 替换为你的Excel文件路径// 区分 .xls 和 .xlsxWorkbookworkbook=null;try(FileInputStreamfis=newFileInputStream(filePath)){if(filePath.endsWith(".xlsx")){workbook=newXSSFWorkbook(fis);// .xlsx}elseif(filePath.endsWith(".xls")){workbook=newHSSFWorkbook(fis);// .xls}else{thrownewIllegalArgumentException("不支持的Excel格式");}// 遍历所有sheetfor(Sheetsheet:workbook){System.out.println("===== Sheet名称:"+sheet.getSheetName()+" =====");// 遍历所有行(跳过表头:从第1行开始,rowNum=1)for(Rowrow:sheet){// 遍历该行所有单元格for(Cellcell:row){// 获取单元格值(统一格式)StringcellValue=getCellValue(cell);System.out.print(cellValue+"\t");}System.out.println();// 换行}}}catch(IOExceptione){e.printStackTrace();}finally{if(workbook!=null){try{workbook.close();}catch(IOExceptione){e.printStackTrace();}}}}// 工具方法:统一处理不同类型的单元格值privatestaticStringgetCellValue(Cellcell){if(cell==null){return"";}switch(cell.getCellType()){caseSTRING:// 字符串returncell.getStringCellValue();caseNUMERIC:// 数字/日期if(DateUtil.isCellDateFormatted(cell)){// 日期类型returncell.getDateCellValue().toString();}else{// 数字类型(避免科学计数法)returnString.valueOf(cell.getNumericCellValue());}caseBOOLEAN:// 布尔值returnString.valueOf(cell.getBooleanCellValue());caseFORMULA:// 公式returncell.getCellFormula()+" = "+cell.getCachedFormulaResultType();caseBLANK:// 空单元格return"";default:return"";}}}
场景 2:读取指定sheet和指定行(精准读取)
// 读取指定sheet(索引从0开始,或按名称)Sheetsheet=workbook.getSheetAt(0);// 第一个sheet// 或 Sheet sheet = workbook.getSheet("用户数据"); // 按名称// 读取指定行(如第2行,rowNum=1)RowtargetRow=sheet.getRow(1);if(targetRow!=null){// 读取指定单元格(如第3列,cellNum=2)CelltargetCell=targetRow.getCell(2);Stringvalue=getCellValue(targetCell);System.out.println("指定单元格值:"+value);}// 遍历有效行(跳过空行)intlastRowNum=sheet.getLastRowNum();// 最后一行索引for(introwNum=1;rowNum<=lastRowNum;rowNum++){Rowrow=sheet.getRow(rowNum);if(row==null){continue;// 跳过空行}// 读取该行单元格Stringname=getCellValue(row.getCell(0));// 第1列:姓名Stringage=getCellValue(row.getCell(1));// 第2列:年龄System.out.println("姓名:"+name+",年龄:"+age);}

三、方案 2:EasyExcel 读取 Excel(高性能,推荐大数据量)

EasyExcel 无需加载整个Excel到内存,适合读取十万级以上数据,核心是通过「监听器」逐行读取。

步骤 1:定义数据实体(与Excel表头映射)
importcom.alibaba.excel.annotation.ExcelProperty;importlombok.Data;// 对应Excel的表头:姓名、年龄、手机号@Data// Lombok注解,自动生成get/setpublicclassUserExcelDTO{// value:Excel表头名称,index:列索引(可选)@ExcelProperty(value="姓名",index=0)privateStringname;@ExcelProperty(value="年龄",index=1)privateIntegerage;@ExcelProperty(value="手机号",index=2)privateStringphone;}
步骤 2:自定义监听器(处理读取到的数据)
importcom.alibaba.excel.context.AnalysisContext;importcom.alibaba.excel.event.AnalysisEventListener;importjava.util.ArrayList;importjava.util.List;// 自定义监听器,逐行读取数据并存储publicclassUserExcelListenerextendsAnalysisEventListener<UserExcelDTO>{// 存储读取到的数据privateList<UserExcelDTO>dataList=newArrayList<>();// 每读取一行数据触发@Overridepublicvoidinvoke(UserExcelDTOuser,AnalysisContextcontext){dataList.add(user);System.out.println("读取到数据:"+user);// 可在此处批量处理(如每1000条插入数据库)if(dataList.size()>=1000){handleData();// 处理数据dataList.clear();// 清空}}// 所有数据读取完成后触发@OverridepublicvoiddoAfterAllAnalysed(AnalysisContextcontext){handleData();// 处理剩余数据System.out.println("Excel读取完成,总数据量:"+dataList.size());}// 数据处理逻辑(如插入数据库)privatevoidhandleData(){if(!dataList.isEmpty()){// TODO: 批量插入数据库/业务处理System.out.println("批量处理"+dataList.size()+"条数据");}}// 获取读取到的所有数据publicList<UserExcelDTO>getDataList(){returndataList;}}
步骤 3:读取Excel文件(核心代码)
importcom.alibaba.excel.EasyExcel;importjava.util.List;publicclassEasyExcelReader{publicstaticvoidmain(String[]args){StringfilePath="D:/test.xlsx";// 初始化监听器UserExcelListenerlistener=newUserExcelListener();// 读取Excel(指定文件路径、实体类、监听器)EasyExcel.read(filePath,UserExcelDTO.class,listener).sheet("用户数据")// 指定sheet名称(可选,默认第一个).headRowNumber(1)// 表头行数(默认1行).doRead();// 执行读取// 获取所有数据List<UserExcelDTO>dataList=listener.getDataList();System.out.println("最终读取到的数据:"+dataList);}}

四、关键注意事项

1. 文件路径与权限
  • 确保文件路径无中文/空格(避免FileNotFoundException);
  • 若读取服务器文件,需保证Java进程有文件读取权限(如Linux下chmod 755)。
2. 版本兼容
  • .xls(HSSFWorkbook)最大支持65536行,.xlsx(XSSFWorkbook)无行数限制;
  • EasyExcel 自动兼容两种格式,无需手动区分。
3. 性能优化
  • Apache POI 读取大数据量Excel易内存溢出,需用SXSSFWorkbook(流式读取);
  • EasyExcel 天生适合大数据量,无需额外配置。
4. 日期/数字格式
  • Apache POI 需手动判断日期格式(DateUtil.isCellDateFormatted);
  • EasyExcel 可通过@ExcelProperty(converter = DateConverter.class)自定义格式转换。

五、两种方案对比

方案优点缺点适用场景
Apache POI功能全、兼容所有Excel特性大数据量易内存溢出、代码繁琐小数据量、需操作复杂Excel(公式/宏)
EasyExcel低内存、代码简洁、高性能不支持宏/复杂公式大数据量、普通数据读取(推荐)

六、常见问题解决

1.FileNotFoundException
  • 检查文件路径是否正确(绝对路径/相对路径);
  • 检查文件是否被占用(如Excel未关闭)。
2. 内存溢出(OOM)
  • Apache POI:改用SXSSFWorkbook流式读取;
  • 优先使用 EasyExcel。
3. 日期读取为数字
  • Apache POI:通过DateUtil.isCellDateFormatted判断并转换;
  • EasyExcel:配置日期转换器。

核心原则:小数据量/复杂Excel用 Apache POI,大数据量/普通读取用 EasyExcel;读取时务必处理空单元格和格式转换,避免空指针/格式错误。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 20:02:52

棕榈酰三肽-38:一种“重建肌底”的智能淡纹成分

棕榈酰三肽-38&#xff1a;一种“重建肌底”的智能淡纹成分 棕榈酰三肽-38 Palmitoyl Tripeptide-38与常见的乙酰基六肽-8&#xff08;又称阿基瑞林&#xff09;作用机理完全不同&#xff0c;代表了抗老淡纹的另一种前沿思路。 核心机理对比&#xff1a; 乙酰基六肽-8&#xff…

作者头像 李华
网站建设 2026/4/15 5:47:12

高并发系统卡顿排查:全链路压测平台对比与瓶颈定位指南

核心观点摘要 1. 高并发系统卡顿问题普遍存在于电商、金融等行业&#xff0c;全链路压测是定位性能瓶颈的主流方案&#xff0c;可有效识别接口、数据库、缓存等环节异常。 2. 当前主流全链路压测平台分为SaaS化服务与私有化部署两类&#xff0c;分别在易用性、弹性成本和定…

作者头像 李华
网站建设 2026/4/16 1:51:04

12、使用WRT54G保障无线网络安全

使用WRT54G保障无线网络安全 1. 引言 无线网络安全多年来一直是计算机安全领域的热门话题。未受保护的无线网络很容易被攻破,这可能会泄露个人信息和计算机文件,还可能被用于攻击他人或进行其他不当活动。通过使用多层安全措施,特别是Wi-Fi受保护访问(WPA)或WPA2,可以降…

作者头像 李华
网站建设 2026/4/16 18:04:43

揭秘LoopLLM:大模型Token能耗攻击新路径,一场AI安全的新挑战!

简介 本文揭示了大模型推理过程中的"可用性攻击"威胁&#xff0c;介绍了LoopLLM框架——通过诱导模型陷入重复生成的低熵循环&#xff0c;使其无法自主终止&#xff0c;从而耗尽计算资源。实验证明&#xff0c;LoopLLM在攻击成功率(>90%)和跨模型迁移能力上显著优…

作者头像 李华
网站建设 2026/4/15 14:46:57

关于雷劈数的一些研究

一、雷劈数的定义背景&#xff1a;有个数学家走在路上看见一个 3025 的路牌被劈成 30 和 25 了&#xff0c;他发现 (3025)23025&#xff0c;因此称这种数为雷劈数。比较小的雷劈数有 81(81)2,100(100)2。雷劈数的定义大概为&#xff1a;将数 N的十进制表示从某处分成两半 a和 b…

作者头像 李华
网站建设 2026/4/17 9:41:53

14、优化 Windows 媒体体验:全方位定制指南

优化 Windows 媒体体验:全方位定制指南 在使用 Windows 系统时,Windows Media Player 和 Windows Media Center 为我们提供了丰富的媒体播放和管理功能。通过对它们进行定制,我们可以让媒体体验更加个性化和高效。下面就来详细介绍如何对它们进行定制。 调整 Windows Medi…

作者头像 李华