栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java导入excel数据为树形处理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java导入excel数据为树形处理

文章目录
  • 前言
  • 一:拆分原始数据
    • 1.创建实体类
    • 2.处理数据,将数据源拆分为若干棵树的数据集
  • 二:手动设置每棵树每个节点的id以及父id
  • 三:递归封装为树结构
  • 总结


前言 今天收到一个导入的任务,要求将excel数据保存到数据库中,不同于普通的导入,这个导入的数据是一个树形结构,如下图:


通过观察数据中的层级列我们发现表格数据由2棵树组成,分别是第3,4,5,6,7,8,9,10,11和12,13,14,15,16,17,18,它们由0作树的根节点,1为0的子节点,2为相邻1的子节点,由此得出第一颗树的结构为:


一:拆分原始数据 1.创建实体类

创建vo接收解析数据,在这里,我们只关心层级属性

	@Excel(name = "层级")
    private String hierarchy;
    @Excel(name = "物料编码")
    private String materialCode;
    @Excel(name = "物料名称")
    private String materialName;
    @Excel(name = "基础数量")
    private BigDecimal materialNum;
    @Excel(name = "使用数量")
    private BigDecimal useAmount;
    @Excel(name = "BOM版本")
    private String version;
    @Excel(name = "默认BOM")
    private String isDefaults;
2.处理数据,将数据源拆分为若干棵树的数据集

代码如下(示例):

    private List> subsection(List materialVos, String s) {
        List> segmentedData = new ArrayList<>();
        if (materialVos != null) {
            //获取指定元素的数量,判断出最终将拆分为多少段
            List collect = materialVos.stream().filter(bom -> s.equals(bom.getHierarchy())).collect(Collectors.toList());
            int count = 0;
            for (int i = 0; i < collect.size(); i++) {
                List bomimportVo = new ArrayList<>();
                boolean num = false;
                //遍历数据源
                for (; count < materialVos.size(); count++) {
                    //第一个必然为树的根节点,直接获取并跳过
                    if (count == 0) {
                        bomimportVo.add(materialVos.get(count));
                        continue;
                    }
                    //当数据源第n个等于根节点并且已经成功添加过数据时判断为一段数据的结束,跳出循环,
                    if (s.equals(materialVos.get(count).getHierarchy()) && num) {
                        break;
                    }
                    bomimportVo.add(materialVos.get(count));
                    num = true;
                }
                segmentedData.add(bomimportVo);
            }
        }
        return segmentedData;
    }

二:手动设置每棵树每个节点的id以及父id

代码如下(示例):

for (List segmentedDatum : subsection(materialVos, "0")) {
                //设置id以及父id
                int i = 0;
                for (MatMaterialBomimportVo vo : segmentedDatum) {
                    BeanTrim.beanAttributevalueTrim(vo);
                    vo.setPrimaryKey(i);
                    getParentId(vo, segmentedDatum);
                    i++;
                }
}

    private void getParentId(MatMaterialBomimportVo vo, List segmentedDatum) {
        for (int j = vo.getPrimaryKey(); j >= 0; j--) {
            if (Integer.parseInt(segmentedDatum.get(j).getHierarchy()) == Integer.parseInt(vo.getHierarchy()) - 1) {
                vo.setForeignKey(segmentedDatum.get(j).getPrimaryKey());
                break;
            }
            if (j == 0) {
                vo.setForeignKey(-1);
            }
        }
    }

说明:拆分为若干棵树后设置每条数据的虚拟id为自己的索引,每棵树的id互相隔离,
根据表格数据规律得出子节点只可能存在于自己节点以下,以及下一个相同节地以上,根据这个规律设置每个节点的父id

三:递归封装为树结构

代码如下(示例):

    private void treeData(MatMaterialBomimportVo vo, List segmentedDatum) {
        for (int i = vo.getPrimaryKey(); i < segmentedDatum.size(); i++) {
            if (i + 1 == segmentedDatum.size()) {
                if (vo.getForeignKey() == null) {
                    getParentId(vo, segmentedDatum);
                }
                break;
            }
            int v = Integer.parseInt(vo.getHierarchy());
            int vs = Integer.parseInt(segmentedDatum.get(i + 1).getHierarchy());
            if (vs == v + 1) {
                if (v > 1) {
                    vo.setForeignKey(segmentedDatum.get(i).getPrimaryKey());
                    for (int j = vo.getPrimaryKey(); j > 0; j--) {
                        if (Integer.parseInt(segmentedDatum.get(j).getHierarchy()) == Integer.parseInt(vo.getHierarchy()) - 1) {
                            vo.setForeignKey(segmentedDatum.get(j).getPrimaryKey());
                        }
                    }
                }
                vo.getimportVoList().add(segmentedDatum.get(i + 1));
            }
            if (vs <= v) {
                if (vo.getForeignKey() == null) {
                    for (int j = vo.getPrimaryKey(); j > 0; j--) {
                        if (Integer.parseInt(segmentedDatum.get(j).getHierarchy()) == Integer.parseInt(vo.getHierarchy()) - 1) {
                            vo.setForeignKey(segmentedDatum.get(j).getPrimaryKey());
                            break;
                        }
                    }
                }
                break;
            }
        }
        if (vo.getimportVoList() != null && vo.getimportVoList().size() > 0) {
            for (MatMaterialBomimportVo matMaterialBomimportVo : vo.getimportVoList()) {
                treeData(matMaterialBomimportVo, segmentedDatum);
            }
        }
    }

说明:我这里传进来的vo是没有设置id和父id的,只对数据源做了树拆分处理,因为业务需求,后面并没有使用这套递归的方法组装为树,所以递归代码可能有点误差,仅供参考

总结

这里主要针对导入数据为树形,以及没有具体的id以及父id的处理,在拆分开没棵树的数据并且每棵树的节点有了父子关系后就可以通过正常的流程处理

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682738.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号