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

使用Apache POI读取Excel日期存入PostgreSQL遇类型错误求助

Apache POI读取Excel日期报错的解决办法

我在用Apache POI读取Excel文件中的日期并准备存入PostgreSQL时遇到问题,使用的代码如下:

FileInputStream inputStream = new FileInputStream(excelFilePath);

Workbook workbook = new XSSFWorkbook(inputStream);

Sheet firstSheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = firstSheet.iterator();

Cell nextCell = cellIterator.next();
Date testTimestamp = nextCell.getDateCellValue();

运行后报错:

Cannot get a NUMERIC value from a STRING cell

Excel中对应列的类型已经试过General、Date、Time、Text、Number,单元格值格式为2023-10-11 13:20:43.000。


问题原因

报错核心是当前单元格实际存储为字符串类型,即便你修改了列的格式设置,Excel也未必会自动把字符串转成日期数值类型——这种情况常见于导入数据、复制粘贴生成的单元格,表面显示是日期,实际底层是字符串。

解决办法

1. 代码层面:先判断单元格类型再处理

Apache POI读取单元格时必须匹配其实际类型,不能直接调用getDateCellValue(),修改代码如下:

Cell nextCell = cellIterator.next();
Date testTimestamp = null;

// 根据单元格实际类型做对应处理
switch (nextCell.getCellType()) {
    case NUMERIC:
        if (DateUtil.isCellDateFormatted(nextCell)) {
            // 单元格是日期格式的数值
            testTimestamp = nextCell.getDateCellValue();
        } else {
            // 处理数字格式的时间戳(如果是秒级要乘1000转毫秒)
            testTimestamp = new Date((long) nextCell.getNumericCellValue() * 1000);
        }
        break;
    case STRING:
        // 解析字符串格式的日期
        String dateStr = nextCell.getStringCellValue().trim();
        try {
            // 匹配你的日期格式:yyyy-MM-dd HH:mm:ss.SSS
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            testTimestamp = sdf.parse(dateStr);
        } catch (ParseException e) {
            // 解析失败的处理,比如打日志或抛出业务异常
            e.printStackTrace();
        }
        break;
    case BLANK:
        // 空单元格逻辑,比如设为null或默认值
        break;
    default:
        // 其他类型(比如公式单元格)的处理
        break;
}

2. Excel层面:将单元格转为真正的日期类型

如果不想修改代码,可以先在Excel里把单元格转成真正的日期数值:

  • 选中目标列,右键→「设置单元格格式」,选择「自定义」,格式输入yyyy-MM-dd HH:mm:ss.000,点击确定
  • 批量处理:选中列→「数据」选项卡→「分列」→选择「分隔符号」→下一步→直接点击完成,Excel会自动识别并转换字符串为日期类型

3. 存入PostgreSQL的注意事项

拿到Date对象后,存入PostgreSQL的timestamp类型字段时,推荐用PreparedStatement避免格式问题:

String sql = "INSERT INTO your_table (timestamp_column) VALUES (?)";
PreparedStatement pstmt = connection.prepareStatement(sql);
// 将Date转为Timestamp适配PostgreSQL的timestamp类型
pstmt.setTimestamp(1, new Timestamp(testTimestamp.getTime()));
pstmt.executeUpdate();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 01:30:08