使用 Apache POI (经典、功能强大)
Apache POI 是 Java 操作 Office 文件(如 Excel, Word, PowerPoint)最老牌、最全面的库,它支持 .xls (Excel 2003) 和 .xlsx (Excel 2007+) 格式。

添加 Maven 依赖
你需要在你的 pom.xml 文件中添加 POI 的依赖,为了同时支持 .xls 和 .xlsx,建议添加以下依赖:
<dependencies>
<!-- 核心 POI 库,用于处理 .xlsx 格式 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.5</version>
</dependency>
<!-- OOXML 库,用于处理 .xlsx 格式 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
<!-- 用于处理 .xls 格式 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.2.5</version>
</dependency>
</dependencies>
基础代码示例 (导出 .xlsx 文件)
下面是一个最简单的示例,创建一个工作簿,写入一些数据,并将其保存到本地文件。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public class PoiSimpleExport {
public static void main(String[] args) {
// 1. 创建一个新的 XSSFWorkbook 对象 (对应 .xlsx 文件)
Workbook workbook = new XSSFWorkbook();
// 2. 创建一个工作表
Sheet sheet = workbook.createSheet("用户数据");
// 3. 创建表头行
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("ID");
headerRow.createCell(1).setCellValue("姓名");
headerRow.createCell(2).setCellValue("邮箱");
// 4. 创建数据行
Row dataRow1 = sheet.createRow(1);
dataRow1.createCell(0).setCellValue(1);
dataRow1.createCell(1).setCellValue("张三");
dataRow1.createCell(2).setCellValue("zhangsan@example.com");
Row dataRow2 = sheet.createRow(2);
dataRow2.createCell(0).setCellValue(2);
dataRow2.createCell(1).setCellValue("李四");
dataRow2.createCell(2).setCellValue("lisi@example.com");
// 5. 自动调整列宽,使内容能够完整显示
sheet.autoSizeColumn(0);
sheet.autoSizeColumn(1);
sheet.autoSizeColumn(2);
// 6. 将工作簿写入到文件
try (FileOutputStream fileOut = new FileOutputStream("D:/poi_users.xlsx")) {
workbook.write(fileOut);
System.out.println("Excel 文件已成功生成!");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 7. 关闭工作簿,释放资源
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
POI 的优缺点
-
优点:
- 功能极其强大: 几乎支持 Excel 的所有功能,包括复杂的公式、图表、图片、单元格样式(字体、颜色、边框等)、合并单元格等。
- 历史悠久: 社区活跃,文档和示例非常丰富,遇到问题容易找到解决方案。
- 兼容性好: 对旧版
.xls格式和新版.xlsx格式都有很好的支持。
-
缺点:
(图片来源网络,侵删)- 内存消耗大: 在处理大数据量(超过 10 万行)时,POI 会将整个 Excel 文件加载到内存中,容易导致
OutOfMemoryError(内存溢出)。 - API 相对繁琐: 对于简单的导出需求,代码量可能比较多。
- 内存消耗大: 在处理大数据量(超过 10 万行)时,POI 会将整个 Excel 文件加载到内存中,容易导致
使用 EasyExcel (阿里巴巴、高性能、推荐)
EasyExcel 是阿里巴巴开源的一个基于 Java 的、简单、省内存的 Excel 处理工具,它解决了 POI 在处理大数据量时的内存问题,是目前处理 Excel 导入导出的首选方案。
添加 Maven 依赖
<dependencies>
<!-- EasyExcel 核心 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
</dependencies>
基础代码示例 (导出 .xlsx 文件)
EasyExcel 的设计非常优雅,它通过 模板 的方式来定义 Excel 的结构。
步骤 1: 创建数据实体类
这个类将作为 Excel 中一行数据的映射。

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
// 使用 Lombok 简化代码,也可以手动生成 getter/setter
@Data
public class UserData {
// @ExcelProperty 注解用于指定该字段对应 Excel 中的列名
@ExcelProperty("ID")
private Integer id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("邮箱")
private String email;
}
步骤 2: 编写导出逻辑
EasyExcel 提供了非常简单的 API 来写入数据。
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelSimpleExport {
public static void main(String[] args) {
// 1. 准备数据
List<UserData> dataList = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
UserData data = new UserData();
data.setId(i);
data.setName("用户" + i);
data.setEmail("user" + i + "@example.com");
dataList.add(data);
}
// 2. 指定输出文件路径
String fileName = "D:/easyexcel_users.xlsx";
// 3. 写入 Excel
// EasyExcel.write(fileName, 数据实体类.class).sheet("工作表名").doWrite(数据集合);
EasyExcel.write(fileName, UserData.class)
.sheet("用户数据")
.doWrite(dataList);
System.out.println("EasyExcel Excel 文件已成功生成!");
}
}
EasyExcel 的优缺点
-
优点:
- 内存友好: 这是它最大的优点,EasyExcel 采用 SAX (Simple API for XML) 模式进行读写,不会将整个文件加载到内存,因此在处理大数据量(百万行级别)时依然能保持低内存占用。
- API 简洁: 代码非常简洁,几行代码就能完成导出,大大提高了开发效率。
- 功能完善: 除了基础的读写,还支持复杂表头、数据转换、自定义样式、模板填充等高级功能。
- 性能高: 经过阿里巴巴内部大量业务场景的验证,性能和稳定性都非常出色。
-
缺点:
- 功能略逊于 POI: 对于一些极其冷门的、非常底层的 Excel 特性,可能 POI 支持得更好,但对于 99% 的业务场景,EasyExcel 已经足够。
- 主要支持
.xlsx: EasyExcel 主要基于 OOXML 格式(即.xlsx),对旧版.xls的支持有限或不推荐。
对比总结与选型建议
| 特性 | Apache POI | EasyExcel |
|---|---|---|
| 内存占用 | 高,大数据量易 OOM | 极低,支持流式读写,大数据量无忧 |
| API 易用性 | 相对繁琐,代码量多 | 非常简洁,开发效率高 |
| 功能完整性 | 极其强大,支持所有 Excel 功能 | 功能齐全,能满足绝大多数业务需求 |
| 性能 | 一般 | 高 |
| 大数据量支持 | 差 | 优秀 |
| 主要格式 | .xls, .xlsx |
.xlsx (推荐) |
如何选择?
- 首选 EasyExcel: 对于绝大多数 Java 项目,无论是中小型还是大型,都强烈推荐使用 EasyExcel,它在易用性、性能和内存管理方面都完胜 POI,是当前的主流和最佳实践。
- 考虑 POI 的场景:
- 必须处理
.xls(Excel 2003) 格式。 - 需要使用 POI 提供的一些非常高级、冷门的 Excel 特性,而 EasyExcel 暂未支持。
- 项目历史原因,已经深度集成了 POI,且数据量不大,没有迁移的必要。
- 必须处理
进阶技巧
- 自定义样式: EasyExcel 和 POI 都支持设置单元格的字体、颜色、边框、对齐方式等。
- 复杂表头: 当表头有多行时,可以通过
WriteTable或 POI 的MergedRegion来实现。 - 模板填充: Excel 的格式是固定的,只需要填充数据,可以使用模板功能,提前设计好 Excel 模板文件,然后向其中填充数据,非常灵活。
- Web 导出: 在 Web 应用(如 Spring Boot)中,通常将 Excel 文件作为 HTTP 响应直接下载给用户,而不是保存到服务器硬盘,只需将
FileOutputStream换成response.getOutputStream()即可。
希望这份详细的指南能帮助你掌握 Java 导出 Excel 的方法!
