使用 EasyExcel 转换器自定义时间类型转换

使用 EasyExcel 转换器自定义时间类型转换

每一句话都有后果

请原谅,近期由于生活变故导致文章很少再更新,虽然也没多少粉丝。

我们在使用 EasyExcel 进行导出时,可能需要对数据库查询出来的时间做个处理。
比如:我们从数据库查询出来的时间为 2021-11-27T10:00:00,而我们需要写入 Excel 中的数据则是 2021-11-27 10:00:00 或者是 2021-10-27 或者是 2021-10 这些格式的时候,我们就需要对查询出来的时间字段做个处理,这里不考虑在 sql 中格式化时间,因为太影响性能。

每一次沉默也是如此

  • EasyExcel 中自定义类型转换都需要实现 Converter 这个接口;在实现之前,我们先了解下 EasyExcel 的 converter 加载流程。

  • 首先来看 EasyExcel 全局 Converter 加载器类:DefaultConverterLoader:
    使用 EasyExcel 转换器自定义时间类型转换_第1张图片

这里可以看到 EasyExcel 有两个私有的静态属性 defaultWriteConverter 与 allConverter,接着通过静态代码块对其进行了赋值。

使用 EasyExcel 转换器自定义时间类型转换_第2张图片

详细可查看 com.alibaba.excel.converters 包下的 DefaultConverterLoader 类。

其实就是调用 putWriteConverter()、putAllConverter()方法放入转换器,初始化默认的加载器之后反射调用方法就好了。
使用 EasyExcel 转换器自定义时间类型转换_第3张图片

使用 EasyExcel 转换器自定义时间类型转换_第4张图片

长话短说,接下来我们进入实际操作阶段:

年月日时分秒类型的处理

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 自定义时间格式转换器
 *
 * 格式:yyyy-MM-dd HH:mm:ss 可任意修改
 *
 * @author Greenarrow
 *
 */
public class LocalDateTimeConverter implements Converter {
    @Override
    public Class supportJavaTypeKey() {
        return LocalDateTime.class;
    }

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

    @Override
    public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    @Override
    public CellData convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return new CellData(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }
}

年月日类型的处理

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 自定义时间格式转换器
 *
 * 格式:yyyy-MM-dd
 *
 * @author Greenarrow
 */
public class LocalDateConverter implements Converter {

    @Override
    public Class supportJavaTypeKey() {
        return LocalDate.class;
    }

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

    @Override
    public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    @Override
    public CellData convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return new CellData(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    }
}

年月类型的处理

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 自定义月消费时间格式转换器
 *
 * 格式:yyyy-MM
 *
 * @author Greenarrow
 */
public class LocalMonthConverter implements Converter {
    @Override
    public Class supportJavaTypeKey() {
        return LocalDate.class;
    }

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

    @Override
    public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    @Override
    public CellData convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return new CellData(value.format(DateTimeFormatter.ofPattern("yyyy-MM")));
    }
}

我们可以看到大体都一致,无非就是格式不一样的问题。

就算不受神的眷顾

接下来我们只需要在导出实体数据模型相应字段添加如下内容:

    @ExcelProperty(value = "创建时间",converter = LocalDateTimeConverter.class)
    private LocalDateTime createTime;

    @ExcelProperty(value = "支付时间",converter = LocalDateTimeConverter.class)
    private LocalDateTime payTime;

OK,到了这里已经结束了。

还是可以选择热爱

该方法的优缺点如下:

  • 优点:只需在每个需要转换的字段上添加自定义 converter 即可

  • 缺点:如果有很多类,每个类中有很多需要单独转换的字段我们就要写很多个,比较繁琐

  • 适用场景:任何场景

你可能感兴趣的:(java)