杰瑞科技汇

Java读取Excel时间格式如何正确解析?

Java 读取 Excel 中的时间数据

在 Java 中读取 Excel 文件中的时间数据需要注意 Excel 存储日期/时间的特殊方式,以下是几种常用的方法:

使用 Apache POI 读取 Excel 时间

Apache POI 是最常用的 Java 操作 Excel 的库。

基本步骤

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 ExcelDateReader {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("example.xlsx");
        Workbook workbook = new XSSFWorkbook(fis);
        Sheet sheet = workbook.getSheetAt(0);
        // 假设时间在第一行第一列
        Row row = sheet.getRow(0);
        Cell cell = row.getCell(0);
        // 处理日期单元格
        if (cell.getCellType() == CellType.NUMERIC) {
            // 检查是否是日期格式
            if (DateUtil.isCellDateFormatted(cell)) {
                Date date = cell.getDateCellValue();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                System.out.println("日期: " + sdf.format(date));
            } else {
                // 如果不是日期格式,可能是数字
                double numericValue = cell.getNumericCellValue();
                System.out.println("数字: " + numericValue);
            }
        } else if (cell.getCellType() == CellType.STRING) {
            // 如果是字符串格式,尝试解析
            String dateStr = cell.getStringCellValue();
            System.out.println("字符串: " + dateStr);
        }
        workbook.close();
        fis.close();
    }
}

处理不同日期格式

// 获取单元格的日期格式
CellStyle cellStyle = cell.getCellStyle();
short formatIndex = cellStyle.getDataFormat();
String formatStr = cellStyle.getDataFormatString();
// 使用 POI 的 DateFormat 处理
DataFormatter dataFormatter = new DataFormatter();
String formattedDate = dataFormatter.formatCellValue(cell);
System.out.println("格式化日期: " + formattedDate);

使用 EasyExcel 读取时间

EasyExcel 是阿里巴巴开源的 Excel 处理库,性能更好。

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadRowHolder;
import java.text.SimpleDateFormat;
import java.util.Date;
public class EasyExcelDateReader {
    public static void main(String[] args) {
        String fileName = "example.xlsx";
        EasyExcel.read(fileName, ExcelData.class, new AnalysisEventListener<ExcelData>() {
            @Override
            public void invoke(ExcelData data, AnalysisContext context) {
                // 假设日期字段名为dateField
                if (data.getDateField() != null) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    System.out.println("日期: " + sdf.format(data.getDateField()));
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                System.out.println("读取完成");
            }
            // 处理日期格式
            @Override
            public void extraRead(CellData cellData, ReadRowHolder readRowHolder) {
                if (cellData.getType() == CellData.DateType.NUMBER) {
                    Date date = cellData.getDateValue();
                    readRowHolder.getCurrentRowHolder().getCurrentRow()
                            .getCell(readRowHolder.getCellIndex())
                            .setCellValue(date);
                }
            }
        }).sheet().doRead();
    }
}
// 定义实体类
class ExcelData {
    @ExcelProperty("日期")
    private Date dateField;
    // getters and setters
}

处理 Excel 日期数字

Excel 中日期实际上是存储为数字的,从 1900/1/1 开始的天数。

// 将 Excel 序列号转换为 Java Date
public static Date excelDateToDate(double excelDate) {
    // Excel 的日期是从 1900-01-01 开始的,但 Excel 认为是 1900-01-00
    // 所以需要减去 2 天来修正
    // 对于 1900-02-29 这个不存在的日期,Excel 也认为存在
    // 所以需要额外处理
    if (excelDate < 60) {
        // 1900-02-29 之前的情况
        return new Date((long)((excelDate - 2) * 24 * 60 * 60 * 1000));
    } else {
        return new Date((long)((excelDate - 1) * 24 * 60 * 60 * 1000));
    }
}

常见问题解决

问题1:读取的日期是数字而不是日期

原因:单元格没有设置为日期格式 解决:使用 DateUtil.isCellDateFormatted() 检查,或者强制转换为日期

if (cell.getNumericCellValue() > 0) {
    Date date = DateUtil.getJavaDate(cell.getNumericCellValue());
    System.out.println(date);
}

问题2:日期格式不正确

原因:Excel 中的日期格式与 Java 期望的不一致 解决:获取 Excel 中的格式字符串并正确解析

DataFormatter formatter = new DataFormatter();
String formattedDate = formatter.formatCellValue(cell);
System.out.println("原始格式: " + formattedDate);

问题3:时区问题

原因:Excel 和 Java 使用不同的时区 解决:指定时区

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8")); // 设置为东八区
System.out.println(sdf.format(date));

完整示例代码

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.DateUtil;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class CompleteExcelDateExample {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("dates.xlsx");
        Workbook workbook = new XSSFWorkbook(fis);
        Sheet sheet = workbook.getSheetAt(0);
        DataFormatter dataFormatter = new DataFormatter();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        for (Row row : sheet) {
            for (Cell cell : row) {
                switch (cell.getCellType()) {
                    case STRING:
                        System.out.println("字符串: " + cell.getStringCellValue());
                        break;
                    case NUMERIC:
                        if (DateUtil.isCellDateFormatted(cell)) {
                            Date date = cell.getDateCellValue();
                            System.out.println("日期(原始): " + date);
                            System.out.println("日期(格式化): " + sdf.format(date));
                            // 获取 Excel 格式
                            CellStyle style = cell.getCellStyle();
                            String format = style.getDataFormatString();
                            System.out.println("Excel 格式: " + format);
                        } else {
                            System.out.println("数字: " + cell.getNumericCellValue());
                        }
                        break;
                    case BOOLEAN:
                        System.out.println("布尔值: " + cell.getBooleanCellValue());
                        break;
                    case FORMULA:
                        System.out.println("公式: " + cell.getCellFormula());
                        break;
                    default:
                        System.out.println("其他类型");
                }
            }
        }
        workbook.close();
        fis.close();
    }
}

方法应该能帮助你正确处理 Java 读取 Excel 中的时间数据,根据你的具体需求选择合适的方法。

分享:
扫描分享到社交APP
上一篇
下一篇