上一篇
Java导出Excel需先引入POI库,创建工作簿、表、行、单元格,设值后通过输出流写入文件并关闭
核心实现流程
无论使用哪种技术方案,导出的核心流程均包含以下步骤:


- 创建工作簿:对应一个Excel文件,支持
.xls(HSSF)或.xlsx(XSSF)格式。 - 创建工作表:在一个工作簿中可创建多个工作表(Sheet)。
- 填充数据:按行(Row)和单元格(Cell)写入数据,并设置样式。
- 保存文件:通过输出流将数据写入本地文件或提供下载。
主流实现方案对比
| 方案 | 依赖库 | 特点 | 适用场景 |
|---|---|---|---|
| Apache POI | poi + poi-ooxml |
功能强大,支持复杂操作(合并单元格、公式等) | 需要精细控制Excel格式的场景 |
| EasyExcel | easyexcel |
轻量级,快速上手,支持流式写入 | 大容量数据导出,简单业务场景 |
| JXL | jxl |
仅支持.xls格式,轻量但已停止更新 |
老旧项目兼容.xls格式 |
使用Apache POI导出数据
添加Maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
基础代码示例(导出List<String[]>)
import org.apache.poi.ss.usermodel.;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.List;
public class POIExportExample {
public static void main(String[] args) throws Exception {
// 创建工作簿(支持.xlsx)
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
// 模拟数据(每行数据为String数组)
List<String[]> data = Arrays.asList(
new String[]{"姓名", "年龄", "城市"},
new String[]{"张三", "25", "北京"},
new String[]{"李四", "30", "上海"}
);
// 创建标题行
Row headerRow = sheet.createRow(0);
for (int i = 0; i < data.get(0).length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(data.get(0)[i]);
}
// 填充数据行
int rowNum = 1;
for (int i = 1; i < data.size(); i++) {
Row row = sheet.createRow(rowNum++);
String[] rowData = data.get(i);
for (int j = 0; j < rowData.length; j++) {
row.createCell(j).setCellValue(rowData[j]);
}
}
// 自动调整列宽
for (int i = 0; i < data.get(0).length; i++) {
sheet.autoSizeColumn(i);
}
// 写入文件
try (FileOutputStream fos = new FileOutputStream("output.xlsx")) {
workbook.write(fos);
}
workbook.close();
}
}
关键优化点
- 内存优化:处理大数据量时,使用
SXSSFWorkbook(POI的流式API)减少内存占用。 - 样式管理:通过
CellStyle设置字体、颜色、对齐方式等,CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); // 水平居中 style.setFillForegroundColor(IndexedColors.YELLOW.getIndex()); // 黄色背景
使用EasyExcel导出数据
添加Maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.2</version>
</dependency>
基础代码示例(导出对象列表)
import com.alibaba.excel.EasyExcel;
import java.util.List;
import java.util.ArrayList;
public class EasyExcelExample {
public static void main(String[] args) {
// 模拟数据(需为JavaBean)
List<User> data = new ArrayList<>();
data.add(new User("张三", 25, "北京"));
data.add(new User("李四", 30, "上海"));
// 写入Excel文件
EasyExcel.write("output.xlsx", User.class)
.sheet("用户信息")
.doWrite(data);
}
}
// JavaBean示例
class User {
private String name;
private int age;
private String city;
// 必须有无参构造器和Getter/Setter
public User() {}
public User(String name, int age, String city) {
this.name = name;
this.age = age;
this.city = city;
}
// Getter和Setter省略
}
优势说明
- 零XML配置:通过注解(
@ExcelProperty)自动映射字段到列名。 - 流式写入:支持分批写入数据,避免内存溢出。
- 内置样式:自动处理标题、表格线等常见样式。
处理复杂数据结构
| 数据类型 | 实现方案 |
|---|---|
| List<String[]> | 直接按行列填充(参考POI基础示例) |
| Map<String,Object> | 将Map转换为JavaBean或动态创建单元格 |
| 自定义对象 | 使用EasyExcel或POI的反射机制(如BeanUtils)映射对象属性到单元格 |
常见问题与解决方案
Q1:导出的文件打开提示“文件已损坏”
- 原因:输出流未正确关闭,或多人同时写入同一个文件。
- 解决:确保
workbook.close()在try-with-resources块中执行,避免并发写操作。
Q2:导出的Excel日期显示为数字(如45678.0)
- 原因:未设置单元格的日期格式。
- 解决:在POI中创建
DataFormat对象并应用格式:DataFormat format = workbook.createDataFormat(); CellStyle style = workbook.createCellStyle(); style.setDataFormat(format.getFormat("yyyy-MM-dd")); cell.setCellStyle(style);
性能优化建议
- 大数据量分片处理:将数据拆分为多个Sheet或分批次写入(如每次1000行)。
- 复用CellStyle对象:避免重复创建样式对象,提升性能。
- 使用临时文件缓冲:先写入内存中的
ByteArrayOutputStream,再批量写入磁盘。
通过以上方法,可根据实际需求选择适合的技术栈,若需进一步定制(如合并单元格、添加图表),可结合POI的

