使用easypoi导出多级复杂表单时,数据与绑定异常

img

为啥后面的数据离表头越来越远了,是我的数据和表头没对应上吗

代码如下所示

List<ExcelExportEntity> exportList = new ArrayList<>();
        // 创建最底部的一级表头10个
        ExcelExportEntity A1 = new ExcelExportEntity("一级表头A1", "a1", 30);
        ExcelExportEntity A2 = new ExcelExportEntity("一级表头A2", "a2", 30);
        ExcelExportEntity B1 = new ExcelExportEntity("一级表头B1", "b1", 30);
        ExcelExportEntity B2 = new ExcelExportEntity("一级表头B2", "b2", 30);
        ExcelExportEntity B3 = new ExcelExportEntity("一级表头B3", "b3", 30);


        // 创建二级表头,并将二级表头对应的下级一级表头放入其中,以此类推...
        ExcelExportEntity A = new ExcelExportEntity("二级表头A", "a");
        A.setList(Arrays.asList(A1, A2));
        ExcelExportEntity B = new ExcelExportEntity("二级表头B", "b");
        B.setList(Arrays.asList(B1, B2, B3));
        ExcelExportEntity E = new ExcelExportEntity("最终成绩", "sumScore");
        ExcelExportEntity F = new ExcelExportEntity("最终评价等级", "level");

        ExcelExportEntity detail = new ExcelExportEntity("三级表头AA", "detail");
        detail.setList(Arrays.asList(A, B, E, F));

        ExcelExportEntity studentNo = new ExcelExportEntity("学号", "studentNo");
        ExcelExportEntity studentName = new ExcelExportEntity("学生", "studentName");
        ExcelExportEntity sectionName = new ExcelExportEntity("学段", "sectionName");
        ExcelExportEntity gradeName = new ExcelExportEntity("年级", "gradeName");
        ExcelExportEntity className = new ExcelExportEntity("班级", "className");
        exportList.addAll(CollUtil.newArrayList(studentNo, studentName, sectionName, gradeName, className, detail));

        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Map<String, Object> other = new HashMap<>();
            other.put("studentNo", "10086");
            other.put("studentName", "小明");
            other.put("sectionName", "小学");
            other.put("gradeName", "一年级");
            other.put("className", "一班");


            Map<String, Object> a = new HashMap<>();
            Map<String, Object> a1 = new HashMap<>();
            a1.put("a1", "指标1");
            Map<String, Object> a2 = new HashMap<>();
            a2.put("a2", "指标2");
            List<Map<String, Object>> aa = CollUtil.newArrayList(a1, a2);
            a.put("a", aa);


            Map<String, Object> b = new HashMap<>();
            Map<String, Object> b1 = new HashMap<>();
            b1.put("b1", "指标4");
            Map<String, Object> b2 = new HashMap<>();
            b2.put("b2", "指标5");
            Map<String, Object> b3 = new HashMap<>();
            b3.put("b3", "指标6");
            List<Map<String, Object>> bb = CollUtil.newArrayList(b1, b2, b3);
            b.put("b", bb);

            Map<String, Object> sumScore = new HashMap<>();
            sumScore.put("sumScore", "98");
            Map<String, Object> level = new HashMap<>();
            level.put("level", "A");
            List<Map<String, Object>> bList = CollUtil.newArrayList(a, b, sumScore, level);
            other.put("detail", bList);

            list.add(other);
        }


        // 导出的表格
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), exportList, list);
        EasyPoiUtil.downLoadExcelWithFormat("多级动态表头", response, workbook);

是否有同学帮忙解答,我的代码哪里存在问题

代码有问题,封装数据逻辑不对,多套了List。
像最后的bList是一个集合数据,所以把表格展开成多行显示了。
把代码理顺,代码太乱了。

引用 皆我百晓生 小程序回复内容作答:
您的代码中存在一个问题:二级表头的数据命名与表头定义中的字段名不一致。

在定义二级表头时,字段名为"a",而在数据中却使用了"a1"和"a2"。这导致数据与表头的绑定出现异常,使得后面的数据离表头越来越远。

解决方法是将二级表头的字段名与数据中的字段名保持一致,即将二级表头的字段名改为"a1"和"a2":

ExcelExportEntity A = new ExcelExportEntity("二级表头A", "a1");
A.setList(Arrays.asList(A1, A2));
ExcelExportEntity B = new ExcelExportEntity("二级表头B", "b1");
B.setList(Arrays.asList(B1, B2, B3));

这样,数据与表头的绑定才能正确进行,后面的数据就能正确对应到对应的表头上。

【相关推荐】



  • 你可以看下这个问题的回答https://ask.csdn.net/questions/766055
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:easypoi导出数据的两种方式(动态表头导出和静态表头导出)
  • 除此之外, 这篇博客: easypoi按模板导出文件中的 方拾二:这种方式就是自定义加载模板的方式,让你的模板可以随时改变,并且每次导出倒是按照你地址的最新形态来给你导出 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    @GetMapping("/exportByEasypoi")
        public void exportByEasypoi() throws Exception {
            ArrayList<User> users = new ArrayList<User>();
            User user = new User();
            user.setId("1");
            user.setName("小张");
            user.setAge("18");
            user.setTel("138383838383");
            users.add(user);
    
            users.add(new User("2","小王","22","384324324"));
            users.add(new User("3","小3","23","3843243224"));
            users.add(new User("4","小4","24","11122224"));
            users.add(new User("5","小5","25","14654324324"));
    
            File fileIn = new File("C:\\Users\\Administrator\\Desktop\\test\\template.docx");
            File fileOut = new File("C:\\Users\\Administrator\\Desktop\\test\\target.docx");
            OutputStream outputStream = new FileOutputStream(fileOut);
    
            Map<String,Object> data = new HashMap();
            data.put("data",users);
            InputStream inputStream = new FileInputStream(fileIn);
            MyXWPFDocument sourceDocument = new MyXWPFDocument(inputStream);
            WordExportUtil.exportWord07(sourceDocument, data);
            sourceDocument.write(outputStream);
            
            outputStream.close();
        }
    

    导出图片到模板中

    ImageEntity imageEntity = new ImageEntity();
    imageEntity.setUrl(imageUrl);
    imageEntity.setHeight(384);
    imageEntity.setWidth(676);
    imageEntity.setType(ImageEntity.URL);
    previewContractObj.setImage(imageEntity);
    data.put("previewContractObj", previewContractObj);
    

    图片的长宽必须设置,这里设置为多少,导出时显示的大小就是多少
    模板直接引用:
    在这里插入图片描述


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

你的数据结构与表头的结构相匹配。也就是说,如果你有一个二级表头,那么对应的数据也应该以相同的结构嵌套。确保数据的每个部分与表头的标识符相匹配。例如,表头"一级表头A1"对应数据中的"a1",以此类推。


@GetMapping("/exportByEasypoi")
    public void exportByEasypoi() throws Exception {
        ArrayList<User> users = new ArrayList<User>();
        User user = new User();
        user.setId("1");
        user.setName("小张");
        user.setAge("18");
        user.setTel("138383838383");
        users.add(user);
        users.add(new User("2","小王","22","384324324"));
        users.add(new User("3","小3","23","3843243224"));
        users.add(new User("4","小4","24","11122224"));
        users.add(new User("5","小5","25","14654324324"));
        File fileIn = new File("C:\\Users\\Administrator\\Desktop\\test\\template.docx");
        File fileOut = new File("C:\\Users\\Administrator\\Desktop\\test\\target.docx");
        OutputStream outputStream = new FileOutputStream(fileOut);
        Map<String,Object> data = new HashMap();
        data.put("data",users);
        InputStream inputStream = new FileInputStream(fileIn);
        MyXWPFDocument sourceDocument = new MyXWPFDocument(inputStream);
        WordExportUtil.exportWord07(sourceDocument, data);
        sourceDocument.write(outputStream);
        outputStream.close();
 

根据截图和代码,发现出现距离偏移的原因是因为二级表头的列数和对应的数据列数不一致,导致数据和表头不对应。具体来说,二级表头A和B的列数为2和3,但是对应数据集合中每个元素的detail属性中的a和b列表长度都是2,导致B2对应的值偏移了。

解决办法是修改数据集合中每个元素的detail属性对应的数据集合,确保每个二级表头对应的下级一级表头列表长度和数据集合中一致。

示例代码:

List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    Map<String, Object> other = new HashMap<>();
    other.put("studentNo", "10086");
    other.put("studentName", "小明");
    other.put("sectionName", "小学");
    other.put("gradeName", "一年级");
    other.put("className", "一班");


    Map<String, Object> a = new HashMap<>();
    Map<String, Object> a1 = new HashMap<>();
    a1.put("a1", "指标1");
    Map<String, Object> a2 = new HashMap<>();
    a2.put("a2", "指标2");
    List<Map<String, Object>> aa = CollUtil.newArrayList(a1, a2);
    a.put("a", aa);


    Map<String, Object> b = new HashMap<>();
    Map<String, Object> b1 = new HashMap<>();
    b1.put("b1", "指标4");
    Map<String, Object> b2 = new HashMap<>();
    b2.put("b2", "指标5");
    Map<String, Object> b3 = new HashMap<>();
    b3.put("b3", "指标6");
    List<Map<String, Object>> bb = CollUtil.newArrayList(b1, b2, b3);
    b.put("b", bb);

    Map<String, Object> sumScore = new HashMap<>();
    sumScore.put("sumScore", "98");
    Map<String, Object> level = new HashMap<>();
    level.put("level", "A");
    List<Map<String, Object>> bList = CollUtil.newArrayList(a, b, sumScore, level);
    other.put("detail", bList);

    // 对于二级表头B下的三个一级表头,数据集合长度应该是3,因为表头对应的数据列就是三列
    if (i == 0) {
        // 对于第一个元素,将b列表长度改为3
        ((List<Map<String, Object>>) ((Map<String, Object>) other.get("detail")).get("b")).get(1).put("b2", "指标5");
        ((List<Map<String, Object>>) ((Map<String, Object>) other.get("detail")).get("b")).add(new HashMap<String, Object>() {{
            put("b3", "指标7");
        }});
    } else if (i == 1) {
        // 对于第二个元素,将a列表长度改为3
        ((List<Map<String, Object>>) ((Map<String, Object>) other.get("detail")).get("a")).get(0).put("a1", "指标1");
        ((List<Map<String, Object>>) ((Map<String, Object>) other.get("detail")).get("a")).add(new HashMap<String, Object>() {{
            put("a2", "指标8");
        }});
    }

    list.add(other);
}

导出列表的字段和代码写的字段一样,包括个数,仔细检查一下吧

结合GPT给出回答如下请题主参考
首先,根据您提供的信息,可能是数据与表头没有对应上导致了异常。建议检查以下几个方面:

  1. 检查数据集合中是否包含了正确的数据,以及数据的顺序是否和表头定义的顺序一致。

  2. 检查数据实体类中的注解是否正确设置,尤其是属性对应的列名、层级关系、父子关系等。如果存在多级复杂表单,建议使用@ExcelCollection注解来标记复杂属性,并在复杂属性对应的实体类中设置@ExcelCollection@Excel注解。

  3. 通过调试或打印日志等方式,查看具体的异常信息,分析异常原因并进行修复。

以下是一个使用easypoi导出多级复杂表单的示例代码:

// 定义表头
List<ExcelExportEntity> exportList = new ArrayList<>();
ExcelExportEntity entity1 = new ExcelExportEntity("姓名", "name");
ExcelExportEntity entity2 = new ExcelExportEntity("年龄", "age");
ExcelExportEntity entity3 = new ExcelExportEntity("联系方式", "contact");
ExcelExportEntity entity4 = new ExcelExportEntity("电话", "phone");
ExcelExportEntity entity5 = new ExcelExportEntity("邮箱", "email");
entity4.setParent(entity3);
entity5.setParent(entity3);
entity3.getMergeVertical().add(entity4);
entity3.getMergeVertical().add(entity5);
entity1.getChildren().add(entity2);
entity1.getChildren().add(entity3);
exportList.add(entity1);

// 准备数据
List<User> userList = new ArrayList<>();
User user1 = new User("张三", 20, "13312345678", "zhangsan@qq.com");
User user2 = new User("李四", 22, "13512345678", "lisi@qq.com");
userList.add(user1);
userList.add(user2);

// 导出数据
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), exportList, userList);

其中定义了一个表头,包含了多级复杂表头,设置了层级关系和父子关系。准备了一个包含了两个用户信息的数据集合。通过ExcelExportUtil.exportExcel方法导出数据到Excel文件。

您好,出现离表头越来越远的问题可能是因为在创建二级表头时,设置的表头字段名与具体数据的Map中的key不对应,导致数据填充到了错误的位置。您可以逐层检查每个表头的属性名和对应的数据Map中的key是否一致,并进行调整。另外,建议在创建表头时,使用常量或枚举来定义表头属性名,有助于规范命名和避免拼写错误。

根据AI的回答,原因是easypoi在导出多级表头时,会为每一级表头插入空行,以突出表头的层级关系。所以数据离表头越来越远,是因为层级越深,插入的空行越多的结果。

这样设置试试:

ExportParams params = new ExportParams();
// 设置为不插入空行的导出类型
params.setType(ExcelType.BIG_NO_HEAD);

使用EasyPOI导出复杂的Word表格
可以参考下