You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apache POI转XLSX到CSV时自定义格式日期转为浮点数的求助

解决Apache POI转换XLSX到CSV时自定义日期格式解析失败的问题

问题核心是Apache POI对带区域标识的自定义日期格式(如[$-409]dd\ mmm\ yyyy;@)识别不充分,默认会把这类单元格的日期值当作普通浮点数处理。以下是具体解决步骤:

1. 手动识别日期格式单元格

不管用UserModel还是EventModel,都需要主动判断单元格的格式字符串是否属于日期相关:

  • 获取单元格的CellStyle,提取格式字符串dataFormatString
  • 直接匹配目标自定义格式,或通过格式字符串中的dd、mmm、yyyy等日期占位符辅助判断(避免漏判类似自定义格式)

2. 手动转换浮点数为目标格式日期

一旦确认是日期单元格,按以下流程处理:

  • 用DateUtil.getJavaDate(double value)将Excel的日期浮点数转为Java Date对象(自动兼容Excel 1900/1904纪元)
  • 针对[$-409]对应的英文(美国)区域,用指定Locale的格式化工具生成目标格式字符串

3. UserModel代码示例

Cell cell = row.getCell(cellIndex);
String cellValue = "";
if (cell != null) {
    CellStyle style = cell.getCellStyle();
    String formatStr = style.getDataFormatString();
    // 判断是否为目标自定义日期格式或日期相关格式
    boolean isTargetDateFormat = formatStr != null && 
        (formatStr.equals("[$-409]dd\\ mmm\\ yyyy;@") || 
        (formatStr.contains("dd") && formatStr.contains("mmm") && formatStr.contains("yyyy")));

    if (cell.getCellType() == CellType.NUMERIC && (DateUtil.isCellDateFormatted(cell) || isTargetDateFormat)) {
        // 转换Excel日期浮点数为Java Date
        Date date = DateUtil.getJavaDate(cell.getNumericCellValue());
        // 按指定格式和Locale生成字符串
        SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy", Locale.US);
        cellValue = sdf.format(date);
    } else {
        // 处理其他数据类型
        switch (cell.getCellType()) {
            case STRING:
                cellValue = cell.getStringCellValue();
                break;
            case NUMERIC:
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA:
                cellValue = cell.getCellFormula();
                break;
            default:
                cellValue = "";
        }
    }
}
// 将cellValue写入CSV文件

4. EventModel处理思路

使用XSSFReader解析时,需要提前加载styles.xml中的所有格式信息:

  • 解析styles.xml,缓存每个格式ID对应的格式字符串
  • 处理单元格数值时,通过格式ID匹配目标日期格式,再执行浮点数到日期的转换

注意事项

  • [$-409]是Excel的区域标识,对应英文(美国),格式化时必须指定Locale.US,否则月份缩写会变成系统默认语言
  • 若存在其他类似自定义日期格式,可扩展格式字符串的判断逻辑
  • Excel的日期浮点数可能存在1900/1904纪元差异,DateUtil.getJavaDate会自动处理该问题

内容的提问来源于stack exchange,提问作者Abhishek Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 18:52:54