使用策略模式和函数式接口实现多种类型数据导出

多种类型的数据导出

一、前言

我们在使用EasyExcel导出的时候,通常都是通过EasyExcel.write(OutputStream outputStream, Class head),这里的Class就是我们需要导出的实体类,一般情况下我们传入一个实体,就能导出数据。
但有时候一个页面中有几个tab页的情况,如果我想分别导出每个tab页的信息,这个时候我们会根据tab页类型去导出各个tab页的数据。如果只有一两个tab页的话,我们可以使用if-else来判断,但是如果有四五个tab页的话,用if-else的话,代码就会显得很臃肿。
为解决这个问题,我们就用到了策略模式函数式编程来实现多种类型的数据导出功能。

二、准备工作

2.1 准备一个导出的类DemoDTO.java,该DTO为数据库查询出来的数据
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class DemoDTO implements Serializable {
    // 其他属性
    // ....
    
    private Demo1DTO demo1DTO;

    private Demo2DTO demo2DTO;

}
2.1. 准备一个导出的基类ExportBaseDTO.java,定义公共的属性,如:index:序号;createTime:创建时间…其他导出的类继承这个基类
@Data
public class ExportBaseDTO extends BaseRowModel {

    @ExcelProperty(index = 0, value = "序号")
    private String index;

    @ExcelProperty(value = "创建时间")
    private String createTime;

}
2.2. 准备2个导出的类Demo1ExportDTO.javaDemo2ExportDTO.java,定义自己的属性,并继承基类ExportBaseDTO.java

注:这里创建2个类做实例,具体根据自己业务需要创建导出的类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Demo1ExportDTO extends ExportBaseDTO {

    @ExcelProperty(value = "编号")
    private String appNo;

    @ExcelProperty(index = 1, value = "买方")
    private String buyerName;

    @ExcelProperty(index = 2, value = "卖方")
    private String sellerName;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Demo2ExportDTO extends ExportBaseDTO {

    @ExcelProperty(value = "编号")
    private String appNo;

    @ExcelProperty(value = "项目名称")
    private String projectName;
}

三、具体实现

3.1 定义2个map和1个List,classHeadMapcopyStrategiesexcludeCols
private Map<TypeEnum, Class<? extends ExportBaseDTO>> classHeadMap = new HashMap<>();
private Map<TypeEnum, CopyPropertiesStrategy> copyStrategies = new HashMap<>();
private List<String> excludeCols = new ArrayList<>();

classHeadMap:key为导出的类型,value为对应的导出实体;
copyStrategies:key为导出的类型,value为策略的接口;
excludeCols:导出的时候某些属性不导出

3.2 定义一个接口
interface CopyPropertiesStrategy {
    void copyProperties(String index, DemoDTO demoDTO, List<ExportBaseDTO> data);
}
3.3 在Bean初始化的时候给maplist赋值
@PostConstruct
private void init() {
    if (classHeadMap.isEmpty()) {
        classHeadMap.put(TypeEnum.DEMO1, Demo1ExportDTO.class);
        classHeadMap.put(TypeEnum.DEMO2, Demo2ExportDTO.class);
    }
    if (copyStrategies.isEmpty()) {
        copyStrategies.put(TypeEnum.DEMO1, ((index, demoDTO, data) -> {
        Demo1ExportDTO demo1ExportDTO = new Demo1ExportDTO();
            Demo1DTO demo1DTO = demoDTO.getDemo1ExportDTO();
            BeanUtils.copyProperties(demo1DTO, demo1ExportDTO);
            // 设置值
            demo1ExportDTO.setIndex(index);
            data.add(demo1ExportDTO);
        }));
        copyStrategies.put(TypeEnum.DEMO2, (index, demoDTO, data) -> {
            Demo2DTO demo2DTO = demoDTO.getDemo2ExportDTO();
            BeanUtils.copyProperties(demo2DTO, demo2ExportDTO);
            // 设置值
            demo2ExportDTO.setIndex(index);
            data.add(demo2ExportDTO);
        });
    }
    if (excludeCols.isEmpty()) {
        // 忽略字段
        excludeCols.add("appNo");
    }
}
3.4 导出方法
@Override
public void export(HttpServletResponse response, TypeEnum type, RoleEnum roleEnum, List<DemoDTO> DemoList) throws IOException {
    setExportHeader(response, type);
    List<ExportBaseDTO> data = new ArrayList<>();
    if (CollectionUtils.isNotEmpty(DemoList)) {
        int index = 0;
        for (DemoDTO demoDTO : DemoList) {
            copyStrategies.get(type).copyProperties(String.valueOf(++index), demoDTO, data);
        }
    }
    if (factorRoleEnum.equals(RoleEnum.TEST_ROLE)) {
        EasyExcel.write(response.getOutputStream(), classHeadMap.get(type)).excludeColumnFiledNames(excludeCols).sheet(type.getDisplayName()).registerWriteHandler(new CustomCellWriteWeightConfig()).doWrite(data);
    } else {
        EasyExcel.write(response.getOutputStream(), classHeadMap.get(type)).sheet(type.getDisplayName()).registerWriteHandler(new CustomCellWriteWeightConfig()).doWrite(data);
    }

}

private static void setExportHeader(HttpServletResponse response, TypeEnum type) throws UnsupportedEncodingException {
    String newFileName = new String((type.getDisplayName() +
            "_" +
            (new SimpleDateFormat("yyyyMMdd")).format(new Date())).getBytes(), "UTF-8") +
            ".xlsx";
    response.setHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(newFileName, "UTF-8") + "\"");
    response.setContentType("application/octet-stream");
}

四、总结

以上便是使用策略模式函数式编程的方式实现多种tab页的导出功能,通过策略模式来消除if-else,使得代码尽量不那么臃肿。另外通过函数式编程,让数据在调用的时候填充到指定的DTO中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值