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

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;读取时务必处理空单元格和格式转换,避免空指针/格式错误。

http://www.cnnetsun.cn/news/62567.html

相关文章:

  • 从 paperxie 到工具矩阵:AI 开题报告工具如何帮你突破 “学术启动瓶颈”?
  • 工具矩阵:开题报告写作的 “规范效率工具箱”——9款 AI 工具的场景化适配实践
  • 咱们唠一下:单例Bean的“出生记”——从“零”到“成品”的全过程
  • Qt快速检测Ubuntu进程状态
  • 73、Sendmail配置参数详解
  • 【超全】基于SSM的企业客户管理系统【包括源码+文档+调试】
  • 数据点的“社交距离”:衡量它们之间的相似与差异
  • 论文格式魔法全书:用Word通配符和宏一键完成专业排版
  • 如果GPT-5.2可以胜任你的大部分工作,你会选择全面拥抱它,还是会恐惧它带来的冲击?它会让你更自由,还是更焦虑?
  • 2026年大模型学习资源全攻略:从零到精通,小白到程序员,一篇超详细的从入门到精通大模型学习指南!
  • 15、优化Windows系统性能:媒体定制与系统分析指南
  • 【软考系统架构设计师】六、软件工程
  • 【Labelme数据操作】LabelMe标注批量复制工具 - 完整教程
  • 数控滑台的基本概念
  • FMD辉芒微电子8位微控制器芯片,荣获“深圳市制造业单项冠军企业”认定
  • Unity XR 编辑器VR设备模拟功能
  • 国产银河麒麟SP3服务器部署mysql主从同步
  • BabylonJS开发:从零基础到项目实战
  • HDF5文件学习笔记
  • Web应用安全头部信息验证方法与测试实践
  • 学校食堂出入库管理软件
  • 基于MATLAB的线性判别分析(LDA)降维算法实现方案
  • 【Java毕设源码分享】基于springboot+vue的线上高校奖助学金系统设计与实现(程序+文档+代码讲解+一条龙定制)
  • 【Java毕设源码分享】基于springboot+vue的高校教室资源管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 被裁后,我却更自由了:不同求职机构的冰与火
  • 从焦虑到从容:这款AI工具如何帮我高效完成5万字硕士论文
  • minio分片上传
  • 基于MATLAB实现深度学习图像分类
  • 9、UNIX/Linux 文件操作全解析
  • 企业SRC支付漏洞EDUSRC众测挖掘思路技巧操作分享