1.前言
最近,对Excel的导出进行了优化,也可以说是修复之前的不足。这个Excel导出的具体任务是导出一个教师的名单。每一个教师都可能存在多个身份,之前对于多个角色的教师信息的展示:
可以很明显的看出导出数据的缺陷,这样的展示会让人误以为这是四个教师,所以为了方便用户观看识别,有必要对一个人多角色的姓名进行一个合并的展示:具体的效果如下:
2.正文
实现的效果其实就是Excel中的合并居中,代码中实现这个的难点就在:
1.身份的鉴别,什么情况下确认这些角色都是同一个人
2.一个教师多个角色数据的行数,也就是合并的起使行数和结束行数
3.单角色的教师是不用合并的,但是会影响到计算多角色的合并
因为我拿出的JSONArray的数据都是几个表的关联查询,一个用户的多个角色信息都是连在一起的,所以相对好判断,代码:
/** * 一个身份多个角色,对名称的合并 * @param pja 入参 * @param index 判断身份的数据 * @return */ public com.alibaba.fastjson.JSONArray getSameData( com.alibaba.fastjson.JSONArray pja , String index ) { logger.debug("开始剖析合并数据"); Set<String> set = new HashSet<>(); //对数据进行遍历 for ( int i = 0; i < pja.size() - 1; i ++ ) { JSONObject jo = pja.getJSONObject( i ); //拿出判断是否是同一个人的判断数据,通常是唯一信息(如:手机号等) String sameI = jo.getString( index ); //计数器,角色的数量,默认是有一个角色的 int count = 1; //如果该数据已经和其他的数据进行相同判断了,下面该身份其他角色就不用再进行判断了 if( set.add( sameI ) ) { //如果之前还没有这个唯一的信息,则加入set set.add( sameI ); //对剩下的数据进行遍历,和之前的进行比较判断 for (int j = i + 1; j < pja.size(); j++) { JSONObject joo = pja.getJSONObject( j ); String sameJ = joo.getString(index); //进行判断 if ( !set.add(sameJ) ) { //如果重复则表明该角色的用户已经存在,角色数量+1 count++; } else { //如果出现新的数据,则将最后出现比较的数据移除set set.remove( sameJ ); //放入起使的行数 jo.put("startRow", i); jo.put("endRow", j - 1); jo.put("num", count); //退出 break; } } } } return pja; }
对数据进行处理后,在重画Excel表格的时候,塞数据时候进行单元格合并就行:
if ( joo.containsKey( "startRow" ) ){ sheet.addMergedRegion( new CellRangeAddress( joo.getInteger("startRow") + 2, joo.getInteger("endRow") + 2, 0 , 0 ) ); }