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

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EasyExcel 是一个非常方便的 Java Excel 工具,可以用于快速读取和写入 Excel 文件。在导入 Excel 数据数据格式校验是很重要的一步,可以避免因为数据格式问题导致的程序异常。下面是一个简单的示例,演示如何使用 EasyExcel 进行数据格式校验: 1. 定义数据模型类,例如: ```java public class User { @ExcelProperty(value = "姓名", index = 0) @NotNull(message = "姓名不能为空") private String name; @ExcelProperty(value = "年龄", index = 1) @Min(value = 18, message = "年龄必须大于等于18") private Integer age; // 省略其他属性和方法 } ``` 在上面的代码中,使用了 Java Bean Validation 的注解来对数据进行校验。例如,@NotNull 注解表示该字段不能为空,@Min 注解表示该字段必须大于等于指定的值。 2. 在读取 Excel 文件,使用 EasyExcel 的 ReadListener 实现类来进行数据校验,例如: ```java public class UserExcelListener extends AnalysisEventListener<User> { private List<User> userList = new ArrayList<>(); @Override public void invoke(User user, AnalysisContext context) { // 数据校验 Set<ConstraintViolation<User>> violations = Validation.buildDefaultValidatorFactory().getValidator().validate(user); if (!violations.isEmpty()) { StringBuilder sb = new StringBuilder(); for (ConstraintViolation<User> violation : violations) { sb.append(violation.getMessage()).append(";"); } throw new RuntimeException("第 " + context.readRowHolder().getRowIndex() + " 行数据校验失败:" + sb.toString()); } // 添加到列表中 userList.add(user); } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 处理完毕后的操作(例如将数据保存到数据库) } public List<User> getUserList() { return userList; } } ``` 在上面的代码中,使用了 Java Bean Validation 的 Validator 来进行数据校验。如果校验失败,抛出异常并提示错误信息。如果校验成功,将数据添加到列表中。 3. 在调用 EasyExcel 的 read() 方法,传入上面定义的 ReadListener 实现类即可,例如: ```java public void importUsers(InputStream inputStream) { try { ExcelReader excelReader = EasyExcel.read(inputStream, User.class, new UserExcelListener()).build(); ReadSheet readSheet = EasyExcel.readSheet(0).build(); excelReader.read(readSheet); excelReader.finish(); } catch (Exception e) { e.printStackTrace(); // 处理异常 } } ``` 在上面的代码中,调用了 EasyExcel 的 read() 方法来读取 Excel 文件,并传入了数据模型类和 ReadListener 实现类。然后调用 readSheet() 方法来指定要读取的 Sheet,最后调用 finish() 方法来完成读取操作。如果出现异常,需要进行异常处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值