easypoi实现动态表头导出

前言

在我们的工作中有时候需要导出的表格为动态的,这个时候我们就无法在实体类定义表头,需要创建一个模板,用模板生成模板,然后在根据生成的模板导出数据

第一步:创建项目(此步骤省略)

第二步:导入easypoi依赖

      <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.4.0</version>
      </dependency>
      <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>

第三步:创建模板

这是手动创建的模板
在这里插入图片描述

第四步:代码实现

Map<String, Object> planDay = getPlanDay(planDayEntity);
        List<Integer> total = new ArrayList<>();
        List<Map> airSourceList = (List<Map>)planDay.get("airSourceList");
        //获取合计的行数
        List<Map> userList = (List<Map>)planDay.get("userList");
        for (int i = 0; i < userList.size(); i++) {
            String stationName = userList.get(i).get("stationName").toString();
            if (stationName.contains("合计")){
                total.add(i);
            }
        }
        //获得相应的表头
        List<Map> headerList = mapper.getHeader(planDayEntity);
        //获取动态顶级表头
        List<Map> bestHeard = mapper.getBestHeard(planDayEntity);
     
        //获取sheet页
        String [] sheetName={"sheet1"};
        try {
            TemplateExportParams templateExportParams = new TemplateExportParams("手动创建模板的路径");
            templateExportParams.setColForEach(true);
            templateExportParams.setSheetName(sheetName);
            templateExportParams.setSheetNum(new Integer[] {0});
            Map<String,Object> map = new HashMap<>();
            map.put("modelList", headerList);
            map.put("header", bestHeard);
            //右侧数据查询
            Workbook workbook = ExcelExportUtil.exportExcel(templateExportParams,map);
            FileOutputStream fileOutputStream= new FileOutputStream(new File("生成模板的路径"));
            workbook.write(fileOutputStream);
            workbook.close();
            fileOutputStream.close();

            TemplateExportParams templateExportParams2 = new TemplateExportParams("生成模板的路径");
            templateExportParams2.setColForEach(true);
            templateExportParams2.setSheetName(sheetName);
            templateExportParams2.setSheetNum(new Integer[] {0});
            Map<String,Object> map2 = new HashMap<>();
            map2.put("userList", userList);
            map2.put("airSourceList", airSourceList);
            //右侧数据查询
            Workbook workbook2 = ExcelExportUtil.exportExcel(templateExportParams2,map2);
            Sheet sheet2 = workbook2.getSheetAt(0);
            //纵向合并
            PoiMergeCellUtil.mergeCells(sheet2, 3, 0, 1);
            //横向合并
            if(airSourceList.size() != 0) {
                PoiMergeCellUtil.addMergedRegion(sheet2, airSourceList.size() + 2, airSourceList.size() + 2, 0, 2);
            }
            if(userList.size() != 0) {
                for (int i = 0; i < total.size()-1; i++) {
                    Integer integer = total.get(i);
                    PoiMergeCellUtil.addMergedRegion(sheet2, airSourceList.size() + integer + 4, airSourceList.size() + integer + 4, 1, 2);
                }
                PoiMergeCellUtil.addMergedRegion(sheet2, airSourceList.size() + userList.size() + 3, airSourceList.size() + userList.size() + 3, 0, 2);
            }
            PoiMergeCellUtil.addMergedRegion(sheet2, 0, 0, 4, bestHeard.size() + 3);
            PoiMergeCellUtil.addMergedRegion(sheet2, 1, 1, 4, bestHeard.size() + 3);
            FileOutputStream fileOutputStream2 = new FileOutputStream(new File("最后模板存放的路径"));
            workbook2.write(fileOutputStream2);
            workbook2.close();
            fileOutputStream2.close();

解释

1、模板中:#代表横向遍历,$代表纵向遍历

2、集合headerList中的数据:[{value=t.2022-09-10, tit=2022-09-10}, {value=t.2022-09-11, tit=2022-09-11}, {value=t.2022-09-12, tit=2022-09-12}, {value=t.2022-09-13, tit=2022-09-13}, {value=t.2022-09-14, tit=2022-09-14}, {value=t.2022-09-15, tit=2022-09-15}, {value=t.2022-09-16}}, tit=2022-09-16}]
3、集合bestHeard中的数据:[{unit=单位:万方、MPa, planDay=日生产计划, day=2022-09-10}, {unit=单位:万方、MPa, planDay=日生产计划, day=2022-09-11}, {unit=单位:万方、MPa, planDay=日生产计划, day=2022-09-12}, {unit=单位:万方、MPa, planDay=日生产计划, day=2022-09-13}, {unit=单位:万方、MPa, planDay=日生产计划, day=2022-09-14}, {unit=单位:万方、MPa, planDay=日生产计划, day=2022-09-15}, {unit=单位:万方、MPa, planDay=日生产计划, day=2022-09-16}]
4、map.put(“modelList”, headerList):key对应手动创建模板中的modelList,value对应headerList的值
5、map.put(“header”, bestHeard):key对应手动创建模板中的header,value对应bestHeard的值

自动生产的模板:

在这里插入图片描述
7、map2.put(“userList”, userList):key对应自动生成模板中的userList,value对应userList的值,userList是查询处的数据
8、 map2.put(“airSourceList”, airSourceList):key对应自动生成模板中的airSourceList,value对应airSourceList的值,airSourceList是查询出的数据

9、Sheet sheet2 = workbook2.getSheetAt(0):表示获取工作表,0代表获取第一个,1代表获取第二个,以此类推
10、PoiMergeCellUtil.mergeCells(sheet2, 3, 0, 1):表示纵向合并,相邻两个单元格值一样就会合并,参数一为工作表,参数二代表从第几行开始合并,参数三表示合并开始的列和合并结束的列
11、PoiMergeCellUtil.addMergedRegion(sheet2, 5, 5, 0, 2):表示横向合并,相邻两个单元格值一样不会合并,需要自己动态获取要合并的行
参数一为工作表,参数二代表从几行开始合并,参数三代表到几行结束合并
参数四代表合并开始列,参数五表示合并结束列

最后导出的样式

在这里插入图片描述

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
使用 EasyPoi 实现动态选择导出表头导出可以通过以下步骤实现: 1. 定义实体类,包含所有需要导出的字段。 2. 定义导出的列配置类,包含所有需要导出的列的名称、字段名、宽度等信息。 3. 在导出功能的Controller中获取要导出的列配置,可以通过前端传递的参数或者从数据库中查询得到。 4. 根据列配置动态生成Excel表头,并将数据写入Excel中。 以下是一个示例代码: ```java // 定义实体类 @Data public class User { private Long id; private String name; private Integer age; private String email; } // 定义导出的列配置类 @Data public class ExportColumn { private String name; // 列名 private String field; // 字段名 private Integer width; // 列宽度 } // 导出功能的Controller @RestController public class UserController { @Autowired private UserService userService; /** * 导出用户列表 * @param columns 导出的列配置 */ @GetMapping("/export") public void export(@RequestParam List<ExportColumn> columns, HttpServletResponse response) throws IOException { // 查询用户列表 List<User> userList = userService.list(); // 设置导出文件名 String fileName = "user_list_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xlsx"; response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=" + fileName); // 创建Excel工作簿 Workbook workbook = new SXSSFWorkbook(1000); Sheet sheet = workbook.createSheet("用户列表"); // 创建表头 Row headerRow = sheet.createRow(0); for (int i = 0; i < columns.size(); i++) { ExportColumn column = columns.get(i); Cell cell = headerRow.createCell(i); cell.setCellValue(column.getName()); sheet.setColumnWidth(i, column.getWidth() * 256); } // 写入数据 for (int i = 0; i < userList.size(); i++) { User user = userList.get(i); Row row = sheet.createRow(i + 1); for (int j = 0; j < columns.size(); j++) { ExportColumn column = columns.get(j); Cell cell = row.createCell(j); try { // 利用反射获取字段值 Field field = user.getClass().getDeclaredField(column.getField()); field.setAccessible(true); Object value = field.get(user); cell.setCellValue(value == null ? "" : value.toString()); } catch (Exception e) { e.printStackTrace(); } } } // 写入响应流 workbook.write(response.getOutputStream()); workbook.close(); } } ``` 在上面的示例代码中,我们通过 `@RequestParam` 获取前端传递的列配置,然后利用 EasyPoi 动态生成表头并写入数据。这样就可以实现动态选择导出表头导出

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值