Apache POI SXSSFWorkbook日期样式不生效问题求助
使用SXSSFWorkbook时日期样式失效的问题
我们的应用基于Apache POI生成Excel表格,因需生成超15万行的大型表格,原XSSFWorkbook导致内存占用飙升至3GB以上,因此切换为滑动窗口模式的SXSSFWorkbook。
大部分功能符合预期(列自动调整需在创建工作表后调用trackAllColumnsForAutoSizing()),但出现核心问题:日期样式设置完全不生效。
现有日期样式创建代码
protected CellStyle createDateCellStyle() { SXSSFCreationHelper createHelper = (SXSSFCreationHelper)workbook.getCreationHelper(); CellStyle cellStyle = workbook.createCellStyle(); cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd.MM.yyyy")); return cellStyle; }
(已尝试将CreationHelper替换为SXSSFCreationHelper,无效果)
单元格样式赋值代码
cell.setCellStyle(dateStyle);
本该显示为日期的单元格全部以整数形式展示,相同代码在XSSFWorkbook全内存模式下完全正常。
当前环境:Java 8、POI 5.2.3(最新版本)、Tomcat 7。
修复方案
这是SXSSF的已知问题,根源在于SXSSF对内置格式与自定义格式的处理逻辑存在差异,直接通过格式字符串获取格式索引无法正确关联日期类型。
方案1:使用内置日期格式索引
POI提供预定义的日期格式索引,直接使用可绕过自定义格式的适配问题:
protected CellStyle createDateCellStyle() { CellStyle cellStyle = workbook.createCellStyle(); // 选用内置的日期格式索引,示例为"dd/mm/yyyy" cellStyle.setDataFormat((short)14); return cellStyle; }
常用内置日期格式索引参考:
- (short)14: dd/mm/yyyy
- (short)22: m/d/yy h:mm
- (short)17: h:mm
方案2:正确注册自定义日期格式
若必须使用自定义格式字符串,需操作SXSSF底层的XSSFWorkbook完成格式注册,并明确指定格式类型:
protected CellStyle createDateCellStyle() { // 获取SXSSF包装的底层XSSFWorkbook XSSFWorkbook xssfWorkbook = (XSSFWorkbook) ((SXSSFWorkbook)workbook).getXSSFWorkbook(); XSSFCreationHelper createHelper = xssfWorkbook.getCreationHelper(); XSSFCellStyle cellStyle = xssfWorkbook.createCellStyle(); // 注册自定义日期格式,避免与内置格式冲突 XSSFDataFormat dataFormat = xssfWorkbook.createDataFormat(); short formatIndex = dataFormat.getFormat("dd.MM.yyyy"); // 关键:明确标记格式类型为日期 xssfWorkbook.getStylesSource().getNumberFormatAt(formatIndex).setFormatType(FormatType.DATE); cellStyle.setDataFormat(formatIndex); return cellStyle; }
额外注意事项
- 避免重复创建大量CellStyle,POI对单元格样式数量有限制,建议全局复用样式对象
- 赋值日期单元格时,确保传入
Date或POI支持的LocalDateTime类型,而非直接传入数字:
// 正确的日期赋值示例 cell.setCellValue(new Date()); // 或POI 5+支持的LocalDateTime cell.setCellValue(LocalDateTime.now());
内容的提问来源于stack exchange,提问作者mmo
相关产品推荐
相关产品推荐

