主流方法概览
| 方法 | 主要库 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| Apache POI | poi, poi-ooxml |
功能最强大,支持所有新旧Excel格式(.xls, .xlsx),社区活跃,文档丰富。 |
依赖库较大,内存消耗高(特别是处理大文件时),API相对繁琐。 | 传统的、功能需求全面的Excel操作,尤其是处理.xls格式。 |
| EasyExcel | easyexcel |
阿里巴巴开源,内存占用极低(基于SAX模型),性能好,API简单易用。 | 相对POI较新,社区和生态不如POI庞大。 | 现代首选,尤其适合处理大数据量的Excel文件,或对内存敏感的应用。 |
| JExcelApi | jxl |
轻量级,API简单,只支持旧版.xls格式。 |
已停止更新多年,不支持.xlsx格式,功能有限。 |
简单的旧版Excel读取任务,且项目依赖要求极轻量。 |
| OpenCSV + Apache POI | opencsv, poi |
专门处理CSV格式,可以与POI结合使用。 | 本质上是处理CSV,并非原生Excel格式。 | 读取或写入CSV(逗号分隔值)文件。 |
Apache POI (功能最全面)
Apache POI是Java操作Office文档的“老牌”和“标准”库,它支持.xls(HSSF)和.xlsx(XSSF)格式。

添加Maven依赖
在你的pom.xml文件中添加以下依赖:
<!-- 用于处理 .xlsx 格式 (Office 2007+) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version> <!-- 建议使用最新稳定版 -->
</dependency>
<!-- 用于处理 .xls 格式 (Office 97-2003) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.5</version>
</dependency>
代码示例 (读取 .xlsx 文件)
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class PoiExcelReader {
public static void main(String[] args) {
String filePath = "path/to/your/file.xlsx"; // 替换为你的Excel文件路径
try (FileInputStream fis = new FileInputStream(filePath);
Workbook workbook = new XSSFWorkbook(fis)) { // 根据文件类型选择 XSSFWorkbook 或 HSSFWorkbook
// 获取第一个工作表
Sheet sheet = workbook.getSheetAt(0);
// 遍历每一行 (从0开始)
for (Row row : sheet) {
// 遍历每一列
for (Cell cell : row) {
// 根据单元格类型获取值
switch (cell.getCellType()) {
case STRING:
System.out.print(cell.getStringCellValue() + "\t");
break;
case NUMERIC:
// 处理日期和数字
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(cell.getDateCellValue() + "\t");
} else {
System.out.print(cell.getNumericCellValue() + "\t");
}
break;
case BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "\t");
break;
case FORMULA:
System.out.print(cell.getCellFormula() + "\t");
break;
default:
System.out.print("UNKNOWN\t");
}
}
System.out.println(); // 换行
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
POI的内存问题
POI在读取.xlsx文件时,默认会将整个文件加载到内存中,如果文件很大(比如几百MB),很容易导致OutOfMemoryError,为了解决这个问题,POI提供了SXSSFWorkbook(流式API),它会在内存中只保留一定数量的行,其余的会临时写入磁盘。
EasyExcel (高性能,推荐)
EasyExcel是阿里巴巴开源的一个项目,它解决了POI的内存问题,在读取大文件时表现优异,API也更简洁。
添加Maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version> <!-- 建议使用最新稳定版 -->
</dependency>
代码示例 (读取 .xlsx 文件)
EasyExcel的核心思想是监听器模式,你定义一个监听器,EasyExcel在读取每一行数据时,会回调监听器中的方法。

第一步:创建数据模型(实体类)
import com.alibaba.excel.annotation.ExcelProperty;
// @ExcelProperty注解用于指定Excel中的列名
public class DemoData {
@ExcelProperty("标题1")
private String string;
@ExcelProperty("标题2")
private Double doubleData;
@ExcelProperty("标题3")
private Integer integer;
// 必须要有无参构造函数
public DemoData() {
}
// Getters and Setters
public String getString() { return string; }
public void setString(String string) { this.string = string; }
public Double getDoubleData() { return doubleData; }
public void setDoubleData(Double doubleData) { this.doubleData = doubleData; }
public Integer getInteger() { return integer; }
public void setInteger(Integer integer) { this.integer = integer; }
@Override
public String toString() {
return "DemoData{" +
"string='" + string + '\'' +
", doubleData=" + doubleData +
", integer=" + integer +
'}';
}
}
第二步:创建监听器
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取new,然后里面用到spring可以构造方法传进去
public class DemoDataListener extends AnalysisEventListener<DemoData> {
// 可以通过实例变量来存储读取到的数据
private List<DemoData> dataList = new ArrayList<>();
/**
* 这个每一条数据解析都会来调用
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(DemoData data, AnalysisContext context) {
System.out.println("解析到一条数据:" + data);
dataList.add(data);
}
/**
* 所有数据解析完成了 都会来调用
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 这里也可以保存数据到数据库
System.out.println("所有数据解析完成!");
System.out.println("总共解析了 " + dataList.size() + " 条数据。");
}
public List<DemoData> getDataList() {
return dataList;
}
}
第三步:编写主程序进行读取
import com.alibaba.excel.EasyExcel;
import java.util.List;
public class EasyExcelReaderDemo {
public static void main(String[] args) {
String fileName = "path/to/your/file.xlsx"; // 替换为你的Excel文件路径
// 需要指定读用哪个class去读,然后读取第一个sheet
DemoDataListener listener = new DemoDataListener();
EasyExcel.read(fileName, DemoData.class, listener).sheet().doRead();
// 读取完成后,可以从监听器中获取数据
List<DemoData> dataList = listener.getDataList();
// ... 对dataList进行后续操作
}
}
如何选择?
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 新项目,对性能和内存有要求 | EasyExcel | API简单,性能好,内存占用低,是现代Java应用处理Excel的首选。 |
| 需要处理非常复杂的Excel格式 | Apache POI | POI功能最全面,能处理各种复杂的样式、图表、公式等。 |
| 项目是旧系统,已经在用POI | Apache POI | 继续使用现有技术栈,避免引入新的依赖和风险,对于大文件,可以考虑升级到SXSSFWorkbook。 |
只是处理简单的.xls文件 |
JExcelApi 或 POI | 如果追求极简,可以用JExcelApi,如果功能可能扩展,用POI更稳妥。 |
| 处理CSV文件 | OpenCSV | 专门为CSV设计,非常高效。 |
- 如果你是新手或正在启动一个新项目,强烈推荐使用 EasyExcel,它的学习曲线更平缓,并且在处理大数据量时表现无与伦比。
- 如果你需要兼容旧系统或处理POI独有的复杂功能,Apache POI 是不二之选。
希望这个详细的解释能帮助你选择最适合你项目的方法!

