EasyExcel导入数据:实现多种时间格式的兼容处理

概述

EasyExcel解析时间格式时,传入的时间格式既有可能为String类型,也有可能为Number类型。因此,需要针对不同的类型,进行特定的转换。该文章主要针对常见的几种时间格式进行转换,方便使用。

支持的时间格式

“yyyy.MM.dd”,
“yyyy/MM/dd”,
“yyyy-MM-dd”,
“yyyyMMdd”

代码


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;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

/**
 * 日期格式转换器
 */
@Slf4j
public class DateConverter implements Converter<Date> {
    // 定义所有要尝试的日期格式
    SimpleDateFormat[] formats = {
        new SimpleDateFormat("yyyy.MM.dd"),
        new SimpleDateFormat("yyyy/MM/dd"),
        new SimpleDateFormat("yyyy-MM-dd"),
        new SimpleDateFormat("yyyyMMdd")
    };

    @Override
    public Class<Date> supportJavaTypeKey() {
        return Date.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public Date convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
                                  GlobalConfiguration globalConfiguration) throws Exception {
        if (cellData.getType().equals(CellDataTypeEnum.NUMBER)) {
            long cellValue = cellData.getNumberValue().longValue();
            if (cellValue > 19900100) {
                try {
                    // 1. 第一种解析,传入的是数字形式的日期,形如yyyyMMdd
                    SimpleDateFormat originalFormat = new SimpleDateFormat("yyyyMMdd");
                    return originalFormat.parse(String.valueOf(cellValue));
                } catch (ParseException e) {
                    log.warn("exception when parse numerical time with format yyyyMMdd");
                }
            }

            // 2. 第二种解析, excel是从1900年开始计算,最终通过计算与1900年间隔的天数计算目标日期
            LocalDate localDate = LocalDate.of(1900, 1, 1);

            //excel 有些奇怪的bug, 导致日期数差2
            localDate = localDate.plusDays(cellValue - 2);

            // 转换为ZonedDateTime(如果需要时区信息)
            ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
            return Date.from(zonedDateTime.toInstant());
        } else if (cellData.getType().equals(CellDataTypeEnum.STRING)) {
            // 3. 第三种解析
            Date date = null;
            String cellValue = cellData.getStringValue();
            for (SimpleDateFormat format : formats) {
                try {
                    date = format.parse(cellValue);
                    if (date != null) {
                        // 这一步是将日期格式化为Java期望的格式
                        return date;
                    }
                } catch (ParseException e) {
                    // 如果有异常,捕捉异常后继续解析
                    log.warn("parse {} exception with format:{}", cellValue, format);
                }
            }
        }
        log.warn("cannot parse the date format");
        return null;
    }
}

参考

https://blog.csdn.net/cristianoxm/article/details/120825814

作者:benniaofei18

物联沃分享整理
物联沃-IOTWORD物联网 » EasyExcel导入数据:实现多种时间格式的兼容处理

发表回复