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

Java读取XLSX文件时日期字段格式异常、解析报错如何解决?

问题原因
  • 直接调用Cell.toString()获取日期值的逻辑错误:POI的Cell.toString()方法不会读取你在Excel中设置的M/d/yyyy自定义格式,会使用POI内置的默认规则输出日期字符串,因此会得到05/Jan/2021这类带英文月份、不符合预期格式的结果。
  • 后续对该不符合规则的字符串做分隔符替换、用M/d/yyyy模板解析/格式化的操作,自然会抛出格式不匹配的异常。
解决方案

你不需要通过字符串中转处理日期,正确逻辑是直接读取单元格的日期对象,再用目标格式做格式化:

  1. 判断单元格为数值类型且是日期格式,调用getDateCellValue()方法直接获取Java Date对象
  2. 用你定义的日期格式化模板直接格式化该Date对象,得到目标格式的字符串

修正后的代码如下:

import org.apache.poi.ss.usermodel.DateUtil;

// ...其余引入和原有代码保持一致
XSSFWorkbook wb1 = new XSSFWorkbook(fis1);   
XSSFSheet sheet1 = wb1.getSheetAt(0);
ArrayList<String> arraylist = new ArrayList<>();

for (Row row : sheet1) {
    Cell cell = row.getCell(4);
    Cell cell2 = row.getCell(5);
    CellType type = cell2.getCellType();
    // 增加日期格式判断,避免普通数值单元格被误处理
    if (type == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell2)) {
        // 直接读取单元格的日期对象,不需要做字符串转换
        Date date = cell2.getDateCellValue();
        SimpleDateFormat dateFor = new SimpleDateFormat("M/d/yyyy");
        String newdate = dateFor.format(date);
        arraylist.add(cell + "-" + newdate);
    }
}
优化建议

SimpleDateFormat是线程不安全的类,如果你的代码是多线程环境运行,建议使用Java 8及以上版本提供的DateTimeFormatter替代,示例逻辑如下:

// DateTimeFormatter是线程安全的,可以定义为全局常量复用
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");

// 格式化逻辑
String newdate = date.toInstant()
        .atZone(ZoneId.systemDefault())
        .toLocalDate()
        .format(formatter);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:36:03