java - poi递归导出树结构Excel,导入树结构Excel,树结构递归查询,新增,修改,删除

工作中设计树结构增删改查,导入,导出操作,搜索 POI导入导出树结构Excle 相关博客较少,故写博客用以记录分享。


一、表结构设计,导入导出模板。

注: 博主树结构为8级结构,因业务关系,故分为两张表。此表分为4级结构如下:
楼栋 — 单元 — 楼层 — 房间

导入导出Excel表格第一列项目名不在此表范围内,忽略此列即可

表仅截取几个树结构相关字段,业务字段根据需求自己添加即可。
在这里插入图片描述
导出Excel样式如下。
在这里插入图片描述

导入Excel模板样式如下:
在这里插入图片描述
在这里插入图片描述

二、递归查询树结构

1.思路如下

  1. 因博主结构层级较多分为两级处理,所以副表可理解为详情表,详情表树结构数据均对应有主表项目id。
  2. 入参:项目id 根据入参先获取此项目下所有子级数据集合(包含楼栋、单元、楼层、房间)。
  3. 返回实体需包含子级List字段 与 自定义获取所有叶子节点方法
private List<****> children = new ArrayList<SysDeptInfoTreeVo>();

public int getLeftNum(){
   
    int count = 0 ;
    if (children.isEmpty()){
   
        return 1;
    }else{
   
        for (****  s : children){
   
            count+= s.getLeftNum();
        }
    }
    return count;
}

2.代码示例

        //根据项目id获取此项目下全部数据
   		List<SysDeptInfoTreeVo> sysDeptInfoTreeVoList = deptInfoMapper.selectListByDeptId(sysDeptInfoDto.getDeptId());
        //获取父节点
        List<SysDeptInfoTreeVo> collect = sysDeptInfoTreeVoList.stream().filter(sysDeptInfoTreeVo -> sysDeptInfoTreeVo.getParentId() == 0).map(s -> {
   
            s.setChildren(getChildren(s, sysDeptInfoTreeVoList));
            return s;
        }).sorted(Comparator.comparing(SysDeptInfoTreeVo::getId)).collect(Collectors.toList());
     
  • 代码解读:
  • 从副表即详情表中先获取此项目下所有数据集合。
  • 过滤获取第一级节点,第一级节点无父节点,获取各个第一级节点后设置子节点调用递归方法即可。
 /**
     * 递归查询子节点
     * @param sysDeptInfoTreeVo  根节点
     * @param sysDeptInfos   所有节点
     * @return 根节点信息
     */
    public static List<SysDeptInfoTreeVo> getChildren(SysDeptInfoTreeVo sysDeptInfoTreeVo, List<SysDeptInfoTreeVo> sysDeptInfos) {
   
        List<SysDeptInfoTreeVo> children = sysDeptInfos.stream().filter(s -> sysDeptInfoTreeVo.getId().equals(s.getParentId())).map(sysDeptInfo -> {
   
            System.out.println("'sysDeptInfo' = " + sysDeptInfo.toString());
            sysDeptInfo.setChildren(getChildren(sysDeptInfo,sysDeptInfos));
            return sysDeptInfo;
        }).sorted(Comparator.comparing(SysDeptInfoTreeVo::getId)).collect(Collectors.toList());
        return children;
    }

二、新增树结构

思路如下

  • 新增入参实体需有 parentId 父节点id

  • 新增根据具体业务进行校验

  • 新增需判断是否为第一级节点,
    若是第一级节点,则 父节点id为0 祖级列表为 0 , 等级为 1
    否则 根据 父节点id 先查询父节点,从父节点获取id作为 parentId ,父节点祖级列表+父节点id 作为祖级列表参数,等级 为 父节点等级+1

  • 新增操作分级处理即可,无示例代码

三.树结构修改。

思路如下

  • 修改操作,需根据实际业务修改,博主修改无修改级别操作,故仅为一些校验后直接update。

四、递归删除树结构

1.思路如下

  • 入参:某根节点id,只要获取到此根节点所有子孙级数据,全部删除即可。

2.代码示例

        //根据id获取此项目
        SysDeptInfo sysDeptInfo = deptInfoMapper.selectById(id);
        Assert.isNull(sysDeptInfo,"未查询到项目信息");
        //获取此项目子级集合
        List<SysDeptInfo> sysDeptInfoList = deptInfoMapper.selectList(new QueryWrapper<SysDeptInfo>().eq("dept_id",sysDeptInfo.getDeptId()));
        //此项目下所有子孙级list
        List<SysDeptInfo> list = new ArrayList();
        list.add(sysDeptInfo);
        //调用递归方法
        list = getChildrenList(sysDeptInfo, sysDeptInfoList,list);
     
  • 代码解读:
  • 首先根据某根节点id获取此条数据,然后根据此数据所属项目id即可获取和此根节点所属同一项目下各个级别数据集合,此集合必包含此条数据下的子孙数据。
  • 创建返回list ,此list包含所有要删除的数据集合,包含此节点。
  • 调用递归方法
    /**
     * 递归查询子节点
     * @param sysDeptInfo  根节点
     * @param  sysDeptInfoList 与根节点同属一个项目下的所有数据list
     * @param  list 返回list
     * @return sysDeptInfoList   所有子节点的list集合
     */
    public static List<SysDeptInfo> getChildrenList(SysDeptInfo sysDeptInfo, List<SysDeptInfo> sysDeptInfoList,List<SysDeptInfo> list) {
   
        List<SysDeptInfo> resList = sysDeptInfoList.stream().filter(s -> sysDeptInfo.getId().equals(s.getParentId())).map(s -> {
   
            list.add(s);
            List<SysDeptInfo> childrenList = getChildrenList(s, sysDeptInfoList, list);
            return s;
        }).collect(Collectors.toList());
        return list;
    }
  • 获取所有需删除的list集合后,从表中删除即可。

Excel导入导出参考下方链接根据需求修改完善即可: Java POI完成Excel导入导出示例
参考博主poi版本较低,若用4.开头poi需修改版本不一致某些方法修改的问题,下方代码已修正。

五、树结构递归导出Excel

1.思路如下

  • 导出Excel尚未进行单元格合并操作,哪个大佬写好的话,不介意的话分享至评论区,感谢。
  • 已订正,导出Excel已添加合并单元格功能
  • 已订正,导出Excel层级多表格样式错乱问题
  • 入参:递归查询树结构的 结果Vo

2.代码示例

  • 代码解读:
  • 只需关注 exportTaskSumPoi 和 ExcelChildrenNew 这个方法即可。
  • exportTaskSumPoi 方法从第三行开始创建行、单元格目的:因为博主结构分为主副表,主表叶子节点为副表所属项目,例如 主表叶子精确到—爱情公寓,那么副表 第一级节点 从 楼栋开始,即爱情公寓第一栋楼,只不过博主多加一个字段 项目id,指定这些楼栋,单元,楼层,房间属于某一项目,例:
  • 主表中 爱情公寓id为 105
    在这里插入图片描述
  • 副表中加上dept_id字段用来指定属于哪个项目
    在这里插入图片描述
  • 回归第三行开始创建行、单元格目的从主表中获取项目信息并将项目信息放在第三行第一个单元格中,关注点为下面递归方法ExcelChildrenNew
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.List;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zensun.system.domain.vo.SysDeptInfoTreeVo;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;


/**
 * @program: family-file-pc-b
 * @description: Excel树结构导出Util
 * @author: LYK
 * @create: 2021-05-20 08:37
 **/
@Component
public class ExcelExportUtil {
   

    private int cols = 9;//excel里表格列

    private String sheetTitle = "项目房间信息";

    public void setCols(int cols) {
   
        this.cols = cols;
    }

    public void setSheetTitle(String sheetTitle) {
   
        this.sheetTitle = sheetTitle;
    }

    /**
     * POI : 导出数据,存放于Excel中
     *
     * @param os
     *            输出流 (action: OutputStream os = response.getOutputStream();)
     * @param sysDeptInfoTreeVo
     *            要导出的数据(根数据)
     */
    public  void exportTaskSumPoi(OutputStream os, SysDeptInfoTreeVo sysDeptInfoTreeVo) {
   
        //取出数据源;
        String headTitle = sheetTitle;//标题;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        try {
   
            // 创建Excel工作薄
            Workbook book = null;
            try {
   
                book = new XSSFWorkbook();//excell2007
            } catch (Exception ex) {
   
                book = new HSSFWorkbook();//excell2003
            }
            // 在Excel工作薄中建一张工作表;
            Sheet sheet = book.createSheet(sheetTitle);
            //设置标题和表头;
            createTitle(book, sheet, headTitle);
            createHead(book, sheet);

            int startCellCount = -1 ; //控制第几个单元格开始字段
            int endCellCount = 0;
            int rowCount = 2 ; //控制创建行数字段
            //从第三行开始创建一行  --- 项目信息
            Row row = sheet.createRow(rowCount);
            //创建一个单元格 ----  项目信息
            Cell cell0 = row.createCell(0);
            cell0.setCellValue(sysDeptInfoTreeVo.getDeptName()==null?"null":sysDeptInfoTreeVo.getDeptName());	
            //获取第一级所有子节点数量,+1是单元格 是从第三行开始
            int i = sysDeptInfoTreeVo.getLeftNum()+ 1;
            //合并项目单元格 四个参数分别为 第一个单元格的行号,第二个单元格行号,第一个单元格列号,第二个单元格的列号
            sheet.addMergedRegion(new CellRangeAddress(2,sysDeptInfoTreeVo.getLeftNum()+1,0,0));
            // 获取楼栋信息
            ExcelChildrenNew(row,sysDeptInfoTreeVo, sheet, startCellCount,endCellCount,rowCount);
            // 写入数据 把相应的Excel 工作簿存盘
            book.write(os);
            book.close();
            os.
  • 11
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
将树形结构数据导出Excel 可以使用 JavaPOI 库来实现POI 是一组用于处理 Microsoft Office 文档的 Java 库,包括 Excel、Word、PowerPoint 等文档格式。 具体实现如下: 1. 在 pom.xml 中添加以下依赖: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> ``` 2. 创建 Excel 文件并写入数据。这里以树形结构数据为例,假设已经从数据库中查询到了树形结构数据,可以使用递归的方式将数据写入 Excel 表格中。 ```java public void exportToExcel(List<Node> nodeList, String filePath) throws IOException { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); int rowIndex = 0; for (Node node : nodeList) { rowIndex = writeNodeToExcel(sheet, node, rowIndex, 0); } FileOutputStream outputStream = new FileOutputStream(filePath); workbook.write(outputStream); workbook.close(); } private int writeNodeToExcel(Sheet sheet, Node node, int rowIndex, int level) { Row row = sheet.createRow(rowIndex++); Cell cell = row.createCell(level); cell.setCellValue(node.getName()); for (Node child : node.getChildren()) { rowIndex = writeNodeToExcel(sheet, child, rowIndex, level + 1); } return rowIndex; } ``` 以上代码中,`Node` 表示树形结构中的一个节点,包含了节点名称和子节点列表。`exportToExcel` 方接收一个节点列表和一个文件路径作为参数,将节点列表写入 Excel 文件中。`writeNodeToExcel` 方递归地将节点和子节点写入 Excel 表格中,其中 `level` 参数表示节点的层级。 3. 调用 `exportToExcel` 方将数据导出Excel 文件。 ```java List<Node> nodeList = // 从数据库中查询树形结构数据 String filePath = "/path/to/excel.xlsx"; exportToExcel(nodeList, filePath); ``` 以上就是将树形结构数据导出Excel 的方,代码中省略了异常处理等细节,请根据实际情况进行补充。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值