You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何用Java POI将输入Excel某列数据写入输出Excel并修改日期格式

解决Apache POI修改Excel日期格式但保留原日期值的问题

我完全懂你的困扰——本来只想把日期列的显示格式从mm/dd/yyyy改成dd/mm/yyyy,结果代码反而把日期替换成了当前时间,这肯定不是你想要的效果。核心问题在于你之前的代码可能错误地覆盖了单元格的日期数值,而不是只修改它的显示格式。下面是针对性的修正方案:

核心思路

Excel里的日期本质是一个数值(从1900年1月1日开始累计的天数),我们要做的只是:

  • 读取单元格原有的日期数值(绝对不要新建Date对象替换它)
  • 给单元格绑定新的日期格式样式,保留原数值不变

修正后的完整代码

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

public class ExcelDateFormatter {
    public static void main(String[] args) {
        String inputFilePath = "input.xlsx";
        String outputFilePath = "output.xlsx";
        int targetColumnIndex = 2; // 假设要修改的是第3列(索引从0开始,可根据实际调整)

        try (FileInputStream fis = new FileInputStream(inputFilePath);
             Workbook workbook = new XSSFWorkbook(fis);
             FileOutputStream fos = new FileOutputStream(outputFilePath)) {

            // 预先创建统一的日期格式样式(不要在循环内重复创建,避免Excel体积臃肿)
            CellStyle newDateStyle = workbook.createCellStyle();
            DataFormat dataFormat = workbook.createDataFormat();
            newDateStyle.setDataFormat(dataFormat.getFormat("dd/mm/yyyy"));

            Sheet targetSheet = workbook.getSheetAt(0); // 处理第一个工作表,可按需切换
            for (Row row : targetSheet) {
                // 跳过表头(如果你的表格有表头的话,不需要就删掉这行)
                if (row.getRowNum() == 0) {
                    continue;
                }

                Cell dateCell = row.getCell(targetColumnIndex);
                if (dateCell != null) {
                    // 处理标准日期类型的单元格
                    if (dateCell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(dateCell)) {
                        // 保留原日期值,只应用新格式
                        Date originalDate = dateCell.getDateCellValue();
                        dateCell.setCellStyle(newDateStyle);
                        dateCell.setCellValue(originalDate); // 确保单元格类型维持为日期型
                    }
                    // 额外处理:如果单元格是字符串格式的日期(比如用户手动输入的文本)
                    else if (dateCell.getCellType() == CellType.STRING) {
                        try {
                            Date parsedDate = DateUtil.parseYYYYMMDD(dateCell.getStringCellValue());
                            dateCell.setCellValue(parsedDate);
                            dateCell.setCellStyle(newDateStyle);
                        } catch (Exception e) {
                            // 解析失败则跳过,保留原内容
                            System.out.println("行" + row.getRowNum() + "的日期字符串无法解析:" + dateCell.getStringCellValue());
                        }
                    }
                }
            }

            workbook.write(fos);
            System.out.println("日期格式修改完成,输出文件已生成!");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关键注意点

  • 绝对不要用new Date():之前的错误大概率是因为你用了新的Date对象覆盖原单元格值,导致变成当前时间
  • 复用CellStyle:在循环外创建一次格式样式,避免重复创建造成Excel文件体积过大、性能下降
  • 兼容多种单元格类型:实际场景中可能存在字符串格式的日期,代码里额外做了解析处理,确保格式统一
  • 格式字符串合规:Apache POI支持的格式和Excel内置格式完全一致,dd/mm/yyyy就是日/月/年的显示规则

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

火山引擎 最新活动