树型结构递归导出excel,合并父级单元格

发布于:2025-02-11 ⋅ 阅读:(46) ⋅ 点赞:(0)

树型结构递归导出excel,合并父级单元格

最近遇到一个需求,需要将树型结构列表数据导致至excel表格中,并且要合并父级数据的单元格,类似下图

在这里插入图片描述

通过递归算法真实导出来之后,发现子级节点会有空行,空行原因是父级写在了上一行,子级写在下一行,来呈现一个树结构,类似下图

在这里插入图片描述

因此需要调整递归算法逻辑,判断是叶子节点时,才创建新的一行,否则不创建新行,获取到的数据写在同一行,单元格合并逻辑是遍历到叶子节点列表最后一个时,则合并上一级父节点单元格

完整代码如下

在这里插入代码片
```public void exportWorkCodeExcel(HttpServletResponse response) throws IOException {
        List<WhProject> permissionDataList = whProjectService.getProjectPermissionDataList().stream().sorted(Comparator.comparing(WhProject::getLevel).reversed()).collect(Collectors.toList());
        Integer maxLevel = permissionDataList.stream().findFirst().get().getLevel();
        List<ProjectTreeVo> projectTreeVos = buildTreeUseStream(permissionDataList, 0L);
        String[] CHINESE_DIGITS = {"二", "三", "四", "五", "六", "七", "八", "九"};
        String workCodeHeadTitle = "%s级工时编码";
        String nameHeadTitle = "%s级工时编码名称";
        //创建工作薄
        XSSFWorkbook wb = new XSSFWorkbook();
        //创建工作表
        XSSFSheet sheet = wb.createSheet("工时编码");
        //设置样式
        XSSFCellStyle style = wb.createCellStyle();
        //水平对齐
        style.setAlignment(HorizontalAlignment.CENTER);
        //垂直对齐
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        XSSFFont font = wb.createFont();
        font.setBold(true);
        style.setFont(font);
        //表头
        //冻结表头
        sheet.createFreezePane(0, 1);
        XSSFRow sheet1row1 = sheet.createRow((short) 0);
        sheet1row1.setHeight((short) 480);
        //写入表头
        int circle = 0;
        for(int i = 0,j = 1; i < (maxLevel-1); i++,j = j + 1) {
            String columnCode = String.format(workCodeHeadTitle,CHINESE_DIGITS[i]);
            String columnName = String.format(nameHeadTitle, CHINESE_DIGITS[i]);
            //列
            XSSFCell cellCode = sheet1row1.createCell(i + circle);
            XSSFCell cellName = sheet1row1.createCell(j + circle);
            cellCode.setCellValue(columnCode);
            cellCode.setCellStyle(style);
            cellName.setCellValue(columnName);
            cellName.setCellStyle(style);
            circle = circle + 1;
        }
        //数据开始行
        int rowIndex = 1;
        for (ProjectTreeVo projectTreeVo : projectTreeVos) {
            rowIndex = writeExcel(sheet, projectTreeVo, rowIndex, 0);
        }

        response.setContentType("application/x-download");
        response.setCharacterEncoding("UTF-8");
        String outFileName = URLEncoder.encode("工时编码.xlsx", "UTF-8");
        //修复中文文件名输出乱码
        response.setHeader("Content-disposition", "attachment;filename=" + outFileName + ";" + "filename*=utf-8''" + outFileName);
        // 写入输出流
        OutputStream outputStream = response.getOutputStream();
        wb.write(outputStream);
        outputStream.flush();
        outputStream.close();
        wb.close();
    }

    /**
     * 写数据到excel中
     * @param sheet  表格
     * @param projectTreeVo  当前节点
     * @param rowIndex 行号
     * @param colIndex 列号
     */
    private int writeExcel(XSSFSheet sheet, ProjectTreeVo projectTreeVo, int rowIndex, int colIndex) {
        int startRow = rowIndex;
        Row row = sheet.getRow(rowIndex);
        if(Objects.isNull(row)){
            row = sheet.createRow(rowIndex);
            row.setHeight((short) 380);
        }
        Cell cell1 = row.createCell(colIndex);
        cell1.setCellValue(projectTreeVo.getWorkHourCode());
        //设置单元格宽度
        sheet.setColumnWidth(colIndex, 256 * 25);
        colIndex = colIndex + 1;
        Cell cell2 = row.createCell(colIndex);
        cell2.setCellValue(projectTreeVo.getName());
        //自适应单元格宽度
        //sheet.autoSizeColumn(colIndex);
       sheet.setColumnWidth(colIndex, 256 * 25);

        for (ProjectTreeVo child : projectTreeVo.getChildren()) {
            rowIndex = writeExcel(sheet, child, rowIndex, colIndex + 1);
        }
        int endRow = rowIndex - 1;
        if (startRow < endRow) { // 如果有子节点,则合并父级单元格
            sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, colIndex, colIndex));
            sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, colIndex-1, colIndex-1));
        }
        if(projectTreeVo.getIsLeaf() == 1){
            //遇到最子级时,+1创建新的一行
            rowIndex++;
        }
        return rowIndex;
    }

网站公告

今日签到

点亮在社区的每一天
去签到