如何用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




