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 ) );
}