使用 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 有两个私有的静态属性 defaultWriteConverter 与 allConverter,接着通过静态代码块对其进行了赋值。
详细可查看 com.alibaba.excel.converters 包下的 DefaultConverterLoader 类。
其实就是调用 putWriteConverter()、putAllConverter()方法放入转换器,初始化默认的加载器之后反射调用方法就好了。
长话短说,接下来我们进入实际操作阶段:
年月日时分秒类型的处理
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<LocalDateTime> {
@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<LocalDate> {
@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<LocalDate> {
@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 即可
-
缺点:如果有很多类,每个类中有很多需要单独转换的字段我们就要写很多个,比较繁琐
-
适用场景:任何场景