SXSSFWorkbook(Streaming XSSF Workbook)是 Apache POI 提供的一种 流式 Excel 写入 实现,相比传统的 XSSFWorkbook,它通过 临时文件缓存 和 行级刷新 机制,显著降低了内存占用。以下是其核心优化原理:
1. XSSFWorkbook 的问题(全内存存储)
XSSFWorkbook 在写入 Excel(.xlsx)时:
- 所有数据存储在内存(DOM 方式),包括:
- 单元格数据
- 样式信息
- 公式计算
- 内存占用 = 文件大小 × 放大系数(通常 3-5 倍)
- 例如:100MB 的 Excel 文件,可能需要 300MB~500MB 内存。
- 大文件容易 OOM(OutOfMemoryError)。
2. SXSSFWorkbook 的优化(流式写入)
SXSSFWorkbook 通过以下方式减少内存占用:
(1)行级缓存 + 临时文件
| 机制 | 说明 |
|---|---|
| 只缓存部分行 | 默认缓存 100 行(可配置),超出部分写入临时文件(磁盘)。 |
| 临时文件存储 | 使用 java.io.tmpdir 存储溢出的行数据,减少内存压力。 |
| 按需加载 | 读取时从临时文件恢复数据,而非全量加载到内存。 |
(2)手动刷新(flushRows)
- 可主动调用
sheet.flushRows()强制将缓存行写入磁盘,释放内存。 - 示例:
for (int i = 0; i < 1_000_000; i++) { SXSSFRow row = sheet.createRow(i); row.createCell(0).setCellValue("Row " + i); if (i % 10_000 == 0) { sheet.flushRows(); // 每 1 万行刷新一次 } }
(3)样式共享
- 样式(
CellStyle)和字体(Font)会被复用,避免重复创建。 - 通过
Workbook.createCellStyle()集中管理样式。
(4)自动清理临时文件
- 调用
workbook.dispose()后,自动删除临时文件:try (SXSSFWorkbook workbook = new SXSSFWorkbook(100)) { // 写入数据... } // 自动调用 dispose()
3. 内存对比(XSSF vs SXSSF)
| 场景 | XSSFWorkbook | SXSSFWorkbook |
|---|---|---|
| 存储方式 | 全内存 DOM | 内存 + 磁盘临时文件 |
| 内存占用 | 高(文件大小 × 3~5 倍) | 低(仅缓存指定行数) |
| 适用数据量 | 小文件(<10MB) | 大文件(百万行+) |
| OOM 风险 | 高 | 低 |
4. 适用场景
(1)适合 SXSSF 的情况
- 导出 百万行级 Excel 报表。
- 内存有限(如云服务器、容器环境)。
- 需要长时间运行的批处理任务。
(2)适合 XSSF 的情况
- 小文件(<10MB)快速处理。
- 需要复杂样式、公式计算。
- 频繁随机访问单元格(
SXSSF不支持随机修改已刷新的行)。
5. 注意事项
-
临时文件目录
- 默认使用
java.io.tmpdir,确保磁盘空间充足。 - 可通过
System.setProperty("java.io.tmpdir", "/custom/tmp")修改。
- 默认使用
-
不可逆操作
SXSSF写入磁盘后的行无法再修改(只支持追加)。
-
性能权衡
- 内存换速度:
SXSSF比XSSF稍慢(因涉及磁盘 I/O)。
- 内存换速度:
-
资源释放
- 必须调用
workbook.dispose(),否则临时文件可能残留。
- 必须调用
6. 代码优化建议
// 1. 设置缓存行数(根据数据量调整)
SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
// 2. 写入数据时定期刷新
for (int i = 0; i < 1_000_000; i++) {
SXSSFRow row = sheet.createRow(i);
// ...
if (i % 10_000 == 0) {
sheet.flushRows();
}
}
// 3. 最终保存并清理
try (FileOutputStream fos = new FileOutputStream("big-data.xlsx")) {
workbook.write(fos);
}
workbook.dispose(); // 清理临时文件
总结
SXSSFWorkbook 通过 行级缓存 + 临时文件 的流式写入机制,将内存占用从 O(文件大小) 降低到 O(缓存行数),成为处理大 Excel 文件的 首选方案。
但需注意 不可逆写入 和 临时文件管理,避免资源泄漏。
3347

被折叠的 条评论
为什么被折叠?



