在开发中遇到一个问题,就是有一张excel表中的数据时多层级的,不是普通一行一行的,而是,一行对应多行,多行之中的每一行在对应多行数据。形成树形结构:
如上图所示:我遇到的excel表的结构:
导入到数据库中,是有多个表组成的!我要实现把这些数据提取出来西港城一个树形而机构的List,然后转为json,导入数据库。
献上我的核心代码:
// 获取Excel内容public static List<?> getContent(Sheet sheet) {List<Map> list = new ArrayList<>();List<Map> cbfList = new ArrayList<>();List<Map> dkxxList = new ArrayList<>();List<Map> familyList = new ArrayList<>();List<Map> cbfList98=new ArrayList<>();List<Integer> cbfRowsIndex=new ArrayList<Integer>();Map map=new HashMap();List<String> titles=new ArrayList<>();// Excel数据总行数int rowCount = sheet.getLastRowNum();//getPhysicalNumberOfRows();//int columnCount = sheet.getRow(2).getPhysicalNumberOfCells();获取不为空的总列数 getPhysicalNumberOfCells()int columnCount =sheet.getRow(2).getLastCellNum() - sheet.getRow(2).getFirstCellNum();for(int x=0;x<sheet.getRow(2).getPhysicalNumberOfCells();x++){//titles.add(getValue(sheet.getRow(0).getCell(x)));if (StringUtils.isNotNull(getCellValue(sheet.getRow(2),x) != null)){String value =getCellValue(sheet.getRow(2),x).toString();System.out.println(value);titles.add(value);}else{titles.add(null);}}System.out.println("数据字段列表"+JsonUtil.beanToJson(titles));// 遍历首行前三列为发包方数据信息,固定第五行开始为数据行Row rowFbf =sheet.getRow(5);Map mapFbf=new HashMap();for (int j = 0; j <=2; j++) {Cell cell = rowFbf.getCell(j);if (cell != null && cell.getCellTypeEnum() != CellType.BLANK) {mapFbf.put(titles.get(j), getCellValue(rowFbf, j).toString());}}list.add(mapFbf);//下面开始进行正式的数据提取,嵌套lsit,Map形式展示数据for (int i = 5; i<=rowCount; i++){Row cbfRow=sheet.getRow(i);Map mapCbf=new HashMap();int cbfRowIndex = 0;for(int j=3;j<=8;j++){if(StringUtil.isNotEmpty(getCellValue(cbfRow,j).toString())){cbfRowIndex=i;mapCbf.put(titles.get(j),getCellValue(cbfRow,j).toString());mapCbf.put("cbfRowIndex",cbfRowIndex);//System.out.println(getCellValue(row,3).toString());}}//System.out.println("承包方数据的列数:"+titles.indexOf("gsshr"));for(int j=titles.indexOf("cbfdcrq");j<=titles.indexOf("gsshr");j++){//if(StringUtil.isNotEmpty(getCellValue(cbfRow,j).toString())){mapCbf.put(titles.get(j),getCellValue(cbfRow,j).toString());//}}//System.out.println(cbfids);//下面时提取98年承包方信息数据int cbf98index= titles.indexOf("yhzmc98");Map map98=new HashMap();for(int x=cbf98index;x<=columnCount;x++){if(StringUtil.isNotEmpty(getCellValue(cbfRow,x).toString())){mapCbf.put(titles.get(x),getCellValue(cbfRow,x).toString());}}//cbfList98.add(map98);int columnIndex=titles.indexOf("cbfmc");Map dkMap =new HashMap();for(int n=titles.indexOf("sfkbdk");n<=titles.indexOf("dkbdh");n++){//if(StringUtil.isNotEmpty(getCellValue(cbfRow, n).toString())){dkMap.put(titles.get(n), getCellValue(cbfRow, n).toString());dkMap.put("dkRowIndex",i);//}}dkxxList.add(dkMap);//System.out.println("第" + (i+1) + "条承包方地块数据:"+dkMap);Map familiyMap=new HashMap();for(int z=titles.indexOf("cyxm");z<=titles.indexOf("cybdrq");z++){familiyMap.put(titles.get(z),getCellValue(cbfRow,z));familiyMap.put("familyRowIndex",i);}familyList.add(familiyMap);//System.out.println("第" + (i+1) + "条家庭成员数据:"+familyList);if(mapCbf.get("elcbdkzs")!=null&&mapCbf.get("cbfRowIndex")!="0") {//System.out.println("承包方数据行:"+mapCbf.get("cbfRowIndex"));cbfList.add(mapCbf);//System.out.println("第" + (i+1) + "条承包方数据:" + JsonUtil.beanToJson(cbfList));}}//System.out.println("总行数:"+sheet.getLastRowNum());//System.out.println("承包方所有数据:"+cbfList);List<Map> allCbfList =cbfList;for(int y=0;y<cbfList.size();y++){List dkList=new ArrayList<>();List famList=new ArrayList<>();Map cbfMap=cbfList.get(y);//System.out.println("每个承包方的Map数据:"+cbfMap);int cbfRowNum=Integer.parseInt(String.valueOf(cbfMap.get("cbfRowIndex")));//System.out.println("数据:"+cbfRowNum);if(y==cbfList.size()-1){int allRowCount=sheet.getLastRowNum();for(int m=cbfRowNum-5;m<=allRowCount-5;m++){//System.out.println("承包方每一行的序号:"+m);//System.out.println("总行数"+allRowCount);int dkRowIndex=Integer.parseInt(String.valueOf(dkxxList.get(m).get("dkRowIndex")));if(m==(dkRowIndex-5)){if(StringUtil.isNotEmpty(dkxxList.get(m).get("dklb").toString())) {dkxxList.get(m).remove("dkRowIndex");dkList.add(dkxxList.get(m));}//dkList.addAll(dkxxList);}int familyRowIndex=Integer.parseInt(String.valueOf(familyList.get(m).get("familyRowIndex")));if(m==(familyRowIndex-5)){if(StringUtil.isNotEmpty(familyList.get(m).get("cyxm").toString())) {familyList.get(m).remove("familyRowIndex");famList.add(familyList.get(m));}//famList.addAll(familyList);}}}else{Map cbfMap2=cbfList.get(y+1);//System.out.println("本条数据:"+cbfMap);//System.out.println("下一条数据:"+cbfMap2);int cbfRowNum2=Integer.parseInt(String.valueOf(cbfMap2.get("cbfRowIndex")));for(int m=cbfRowNum-5;m<cbfRowNum2-5;m++){//System.out.println("承包方每一行的详细"+m);//System.out.println("所有地块信息的总数:"+dkxxList.size());int dkRowIndex=Integer.parseInt(String.valueOf(dkxxList.get(m).get("dkRowIndex")));//System.out.println("地块信息的行数:"+dkRowIndex);if(m==(dkRowIndex-5)){if(StringUtil.isNotEmpty(dkxxList.get(m).get("dklb").toString())) {dkxxList.get(m).remove("dkRowIndex");dkList.add(dkxxList.get(m));}//dkList.addAll(dkxxList);//System.out.println("map数据"+dkxxList.get(m));}int familyRowIndex=Integer.parseInt(String.valueOf(familyList.get(m).get("familyRowIndex")));if(m==(familyRowIndex-5)){if(StringUtil.isNotEmpty(familyList.get(m).get("cyxm").toString())){familyList.get(m).remove("familyRowIndex");famList.add(familyList.get(m));}//famList.addAll(familyList);//System.out.println("map数据"+famList);}}}//去除列表中为空的项//famList.removeAll(Collections.singleton(""));//dkList.removeAll(Collections.singleton(""));cbfMap.put("jtcyxx",famList);cbfMap.put("dkxx",dkList);cbfList.get(y).putAll(cbfMap);cbfList.get(y).remove("cbfRowIndex");System.out.println("承包方数据带家庭成员和地块信息:"+cbfMap);}//cbfList =getCbfList(cbfList,sheet,dkxxList,familyList);//去除隶属列表中为空的项cbfList.removeAll(Collections.singleton(null));map.put("allcbf",cbfList);list.add(map);//System.out.println("第" + i + "条承包方数据:" + JsonUtil.beanToJson(list));logger.info("所有数据:"+list);return list;}
首先,Java对excel的操作用有两种:jxl和poi,这里我用的是poi,所以我准备开始思路:第一行的前三列为第一层数据,然后及接着后面二层数据为承包方户主信息,第三层数据为家庭 成员信息还有地块信息。