Java Excel 导入日期处理指南
在Java中处理Excel导入日期数据时,需要注意Excel日期的特殊存储方式,以下是完整的解决方案:

使用Apache POI处理Excel日期
Apache POI是处理Excel文件最常用的Java库。
基本步骤
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExcelDateImporter {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("example.xlsx");
Workbook workbook = new XSSFWorkbook(fis)) {
Sheet sheet = workbook.getSheetAt(0);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
for (Row row : sheet) {
// 假设日期在第一列
Cell cell = row.getCell(0);
if (cell != null) {
switch (cell.getCellType()) {
case NUMERIC:
// 处理日期类型的数字
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
System.out.println("日期: " + dateFormat.format(date));
} else {
// 处理普通数字
System.out.println("数字: " + cell.getNumericCellValue());
}
break;
case STRING:
// 处理字符串格式的日期
String dateStr = cell.getStringCellValue();
System.out.println("字符串日期: " + dateStr);
break;
// 其他类型处理...
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
处理不同日期格式
Excel中的日期可能有多种格式,需要统一处理:
private static Date parseExcelDate(Cell cell) {
if (cell == null) return null;
try {
switch (cell.getCellType()) {
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue();
} else {
// 处理Excel日期序列号
double numericValue = cell.getNumericCellValue();
return DateUtil.getJavaDate(numericValue);
}
case STRING:
String dateStr = cell.getStringCellValue().trim();
if (dateStr.isEmpty()) return null;
// 尝试多种日期格式
String[] patterns = {
"yyyy-MM-dd", "MM/dd/yyyy", "dd-MM-yyyy",
"yyyy年MM月dd日", "yyyyMMdd"
};
for (String pattern : patterns) {
try {
return new SimpleDateFormat(pattern).parse(dateStr);
} catch (Exception e) {
// 继续尝试下一种格式
}
}
throw new IllegalArgumentException("无法解析的日期格式: " + dateStr);
default:
return null;
}
} catch (Exception e) {
throw new RuntimeException("日期解析失败: " + e.getMessage(), e);
}
}
使用EasyExcel处理日期
阿里巴巴的EasyExcel库提供了更简单的API:
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class EasyExcelDateReader {
public static void main(String[] args) {
String fileName = "example.xlsx";
EasyExcel.read(fileName, DateData.class, new AnalysisEventListener<DateData>() {
private List<DateData> dataList = new ArrayList<>();
@Override
public void invoke(DateData data, AnalysisContext context) {
dataList.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("读取完成,共" + dataList.size() + "条数据");
}
}).sheet().doRead();
}
}
// 定义数据模型
class DateData {
@ExcelProperty(value = "日期", converter = CustomDateConverter.class)
private Date date;
// getters and setters
}
自定义日期转换器
如果需要自定义日期格式处理:

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
public class CustomDateConverter implements Converter<Date> {
private static final String[] DATE_FORMATS = {
"yyyy-MM-dd", "yyyy/MM/dd", "yyyy年MM月dd日",
"yyyyMMdd", "MM/dd/yyyy", "dd-MM-yyyy"
};
@Override
public Class<?> supportJavaTypeKey() {
return Date.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public Date convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws Exception {
String dateStr = cellData.getStringValue();
for (String pattern : DATE_FORMATS) {
try {
return new SimpleDateFormat(pattern).parse(dateStr);
} catch (Exception e) {
// 继续尝试下一种格式
}
}
throw new IllegalArgumentException("无法解析的日期格式: " + dateStr);
}
}
注意事项
- Excel日期存储:Excel将日期存储为序列号(1900年1月1日为1)
- 时区问题:处理日期时注意时区转换
- 1900年bug:Excel认为1900年是闰年,实际不是,需要特殊处理
- 空值处理:检查单元格是否为空
- 格式验证:验证日期字符串是否符合预期格式
完整示例
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class CompleteExcelDateImporter {
private static final Map<String, String> DATE_FORMAT_MAP = new HashMap<>();
static {
DATE_FORMAT_MAP.put("yyyy-MM-dd", "日期格式: 年-月-日");
DATE_FORMAT_MAP.put("MM/dd/yyyy", "日期格式: 月/日/年");
DATE_FORMAT_MAP.put("dd-MM-yyyy", "日期格式: 日-月-年");
DATE_FORMAT_MAP.put("yyyy年MM月dd日", "中文日期格式");
DATE_FORMAT_MAP.put("yyyyMMdd", "紧凑日期格式");
}
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("dates.xlsx");
Workbook workbook = new XSSFWorkbook(fis)) {
Sheet sheet = workbook.getSheetAt(0);
int rowNum = 0;
for (Row row : sheet) {
rowNum++;
System.out.println("\n处理第 " + rowNum + " 行:");
for (Cell cell : row) {
processCell(cell);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void processCell(Cell cell) {
if (cell == null) {
System.out.println("单元格为空");
return;
}
switch (cell.getCellType()) {
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
System.out.println("Excel日期格式: " + date);
} else {
double numericValue = cell.getNumericCellValue();
System.out.println("数字值: " + numericValue);
// 尝试将数字转换为日期
try {
Date date = DateUtil.getJavaDate(numericValue);
System.out.println("转换后的日期: " + date);
} catch (Exception e) {
System.out.println("无法转换为日期");
}
}
break;
case STRING:
String strValue = cell.getStringCellValue().trim();
if (strValue.isEmpty()) {
System.out.println("空字符串");
return;
}
// 尝试解析为日期
for (Map.Entry<String, String> entry : DATE_FORMAT_MAP.entrySet()) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(entry.getKey());
Date date = sdf.parse(strValue);
System.out.println(entry.getValue() + ": " + date);
return;
} catch (ParseException e) {
// 继续尝试下一种格式
}
}
System.out.println("无法识别的字符串: " + strValue);
break;
case FORMULA:
System.out.println("公式单元格: " + cell.getCellFormula());
break;
default:
System.out.println("不支持的单元格类型: " + cell.getCellType());
}
}
}
代码提供了从Excel导入日期数据的完整解决方案,包括处理不同日期格式、Excel序列号日期和字符串日期等情况,根据实际需求选择适合的方法即可。
