在项目当中,很多同事喜欢用Map来存储数据,尤其是从数据库查询数据然后存放到List<Map<String,Object>>当中。这样会导致通过excel模板导出时数据错乱。
当前easyexcel版本

 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>easyexcel</artifactId>
     <version>3.1.1</version>
 </dependency>

假如存在以下模板(limitManage2.xlsx)。

日期 操作人 额度周期起始日 额度周期到期日 总额度(元) 剩余额度(元) 备注 状态 机构名称 已领用额度(元) 备注2
{bean.CREATE_DATE} {bean.CREATOR} {bean.LIMIT_CYCLE_START} {bean.LIMIT_CYCLE_MTR} {bean.TOTAL_LIMIT} {bean.SURPLUS_LIMIT} {bean.REMARK} {bean.STATUS} {bean.BRANCH_INSTITUTION_NAME} {bean.GET_LIMIT} {bean.fillData3.REMARK}

首先通过List<Map<String,Object>>填充数据(故意将REMARK字段的值部分设置为空,规则是列表中索引为偶数的为空)

   private static Map<String, Object> data2(){
        Map<String, Object> params = new HashMap<>();
        List<Map<String, String>> result = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Map<String, String> curMap = new HashMap<>();
            curMap.put("CREATE_DATE", "2018-06-12");
            curMap.put("STATUS", "已生效");
            curMap.put("LIMIT_CYCLE_START", "2018-06-12");
            curMap.put("LIMIT_CYCLE_MTR", "2018-06-12");
            curMap.put("BRANCH_INSTITUTION_NAME", "资产管理部");
            curMap.put("SURPLUS_LIMIT", "88888888" + i);
            curMap.put("CREATOR", "系统管理员" + i);
            curMap.put("GET_LIMIT", "101000000");
            curMap.put("PK", "2417");
            curMap.put("TOTAL_LIMIT", "88888888");
            if (i % 2 == 0) {
                curMap.put("REMARK", "定制额度" + i);
            }else {
//                curMap.put("REMARK","");
            }
            result.add(curMap);
        }
        params.put("bean", result);
        return params;
    }

创建测试类

    @Test
    public void compositeFillMapIssue() {
        String templateFileName =
                TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "limitManage2.xlsx";
        System.out.println(new File(templateFileName).getPath());
        String fileName = TestFileUtil.getPath() + "compositeFill" + System.currentTimeMillis() + ".xlsx";

        try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            Map<String, Object> data2 = data2();
            FillConfig fillConfig = FillConfig.builder().build();
            data2.forEach((key,value)->{
                excelWriter.fill(new FillWrapper(key, (List<Map<String, String>>)value),fillConfig, writeSheet);
            });
        }
        System.out.println(new File(fileName).getPath());
    }

测试类路径 src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java
测试模板路径 src/test/resources/demo/fill/limitManage2.xlsx

执行结果如下所示

额度周期到期日 总额度(元) 剩余额度(元) 备注 状态 机构名称 已领用额度(元) 备注2
2018-06-12 88888888 888888880 定制额度0 已生效 资产管理部 101000000
2018-06-12 88888888 888888881 定制额度2 已生效 资产管理部 101000000
2018-06-12 88888888 888888882 定制额度4 已生效 资产管理部 101000000
2018-06-12 88888888 888888883 定制额度6 已生效 资产管理部 101000000
2018-06-12 88888888 888888884 定制额度8 已生效 资产管理部 101000000
2018-06-12 88888888 888888885 定制额度10 已生效 资产管理部 101000000
2018-06-12 88888888 888888886 定制额度12 已生效 资产管理部 101000000
2018-06-12 88888888 888888887 定制额度14 已生效 资产管理部 101000000
2018-06-12 88888888 888888888 定制额度16 已生效 资产管理部 101000000
2018-06-12 88888888 888888889 定制额度18 已生效 资产管理部 101000000
2018-06-12 88888888 8888888810 已生效 资产管理部 101000000
2018-06-12 88888888 8888888811 已生效 资产管理部 101000000
2018-06-12 88888888 8888888812 已生效 资产管理部 101000000
2018-06-12 88888888 8888888813 已生效 资产管理部 101000000
2018-06-12 88888888 8888888814 已生效 资产管理部 101000000
2018-06-12 88888888 8888888815 已生效 资产管理部 101000000
2018-06-12 88888888 8888888816 已生效 资产管理部 101000000
2018-06-12 88888888 8888888817 已生效 资产管理部 101000000
2018-06-12 88888888 8888888818 已生效 资产管理部 101000000
2018-06-12 88888888 8888888819 已生效 资产管理部 101000000

在这里插入图片描述
从上面的结果不难看出,备注栏的信息都错乱了。

通过测试发现,将Map转为对象即可。

pojo定义如下

package com.alibaba.easyexcel.test.demo.fill;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@EqualsAndHashCode
public class FillData2 {

    private String CREATE_DATE;
    private String STATUS;
    private String LIMIT_CYCLE_START;
    private String LIMIT_CYCLE_MTR;
    private String BRANCH_INSTITUTION_NAME;
    private String SURPLUS_LIMIT;
    private String CREATOR;
    private String GET_LIMIT;
    private String PK;
    private String TOTAL_LIMIT;
    private String REMARK;
    private FillData3 fillData3;
}
package com.alibaba.easyexcel.test.demo.fill;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;


@Getter
@Setter
@EqualsAndHashCode
public class FillData3 {

    private String REMARK3;

}

创建测试数据

  private static Map<String, List<FillData2>> data3(){
        Map<String, List<FillData2>> params = new HashMap<>();
        List<FillData2> result = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            FillData2 curMap = new FillData2();

            curMap.setCREATE_DATE("2018-06-12");
            curMap.setSTATUS("已生效");
            curMap.setLIMIT_CYCLE_START("2018-06-12");
            curMap.setLIMIT_CYCLE_MTR("2018-06-12");
            curMap.setBRANCH_INSTITUTION_NAME("资产管理部");
            curMap.setSURPLUS_LIMIT("88888888" + i);
            curMap.setCREATOR("系统管理员" + i);
            curMap.setGET_LIMIT("101000000");
            curMap.setPK("2417");
            curMap.setTOTAL_LIMIT("88888888");
            if (i % 2 == 0) {
                curMap.setREMARK("定制额度" + i);
            }else {
//                curMap.put("REMARK","");
            }
            FillData3 fillData3 = new FillData3();
            fillData3.setREMARK3(curMap.getREMARK() +">>");
            curMap.setFillData3(fillData3);
            result.add(curMap);
        }
        params.put("bean", result);
        return params;
    }

创建测试类

    @Test
    public void compositeFillMapIssue3() {
        String templateFileName =
                TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "limitManage2.xlsx";
        System.out.println(new File(templateFileName).getPath());
        String fileName = TestFileUtil.getPath() + "compositeFill" + System.currentTimeMillis() + ".xlsx";

        // 方案1
        try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            Map<String, List<FillData2>> data2 = data3();
            data2.forEach((key,value)->{
                excelWriter.fill(new FillWrapper(key, value), writeSheet);
            });
        }
        System.out.println(new File(fileName).getPath());
    }

测试结果如下所示

额度周期到期日 总额度(元) 剩余额度(元) 备注 状态 机构名称 已领用额度(元) 备注2
2018-06-12 88888888 888888880 定制额度0 已生效 资产管理部 101000000
2018-06-12 88888888 888888881 已生效 资产管理部 101000000
2018-06-12 88888888 888888882 定制额度2 已生效 资产管理部 101000000
2018-06-12 88888888 888888883 已生效 资产管理部 101000000
2018-06-12 88888888 888888884 定制额度4 已生效 资产管理部 101000000
2018-06-12 88888888 888888885 已生效 资产管理部 101000000
2018-06-12 88888888 888888886 定制额度6 已生效 资产管理部 101000000
2018-06-12 88888888 888888887 已生效 资产管理部 101000000
2018-06-12 88888888 888888888 定制额度8 已生效 资产管理部 101000000
2018-06-12 88888888 888888889 已生效 资产管理部 101000000
2018-06-12 88888888 8888888810 定制额度10 已生效 资产管理部 101000000
2018-06-12 88888888 8888888811 已生效 资产管理部 101000000
2018-06-12 88888888 8888888812 定制额度12 已生效 资产管理部 101000000
2018-06-12 88888888 8888888813 已生效 资产管理部 101000000
2018-06-12 88888888 8888888814 定制额度14 已生效 资产管理部 101000000
2018-06-12 88888888 8888888815 已生效 资产管理部 101000000
2018-06-12 88888888 8888888816 定制额度16 已生效 资产管理部 101000000
2018-06-12 88888888 8888888817 已生效 资产管理部 101000000
2018-06-12 88888888 8888888818 定制额度18 已生效 资产管理部 101000000
2018-06-12 88888888 8888888819 已生效 资产管理部 101000000

在这里插入图片描述
从测试结果可以看出,上面空数据错乱的问题解决了,但是最后一列没有任何数据。对应的模板为{bean.fillData3.REMARK},从这里看出easyexcel对于一个对象中包含复杂对象数据的模板导出不支持。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐