使用poi导出excel生成复杂多级表头通用方法 话不多说,直接上代码,需要用的的实体类如下
话不多说,直接上代码,需要用的的实体类如下
package com.test;
public class UnioExcel {
private Integer firstCol;//合并单元格的起始列坐标
private Integer firstRol;//合并单元格的起始行坐标
private Integer finalCol;//合并单元格的起始的终点列坐标
private Integer finalRol;//合并单元格的起始终点行坐标
public Integer getFirstCol() {
return firstCol;
}
public void setFirstCol(Integer firstCol) {
this.firstCol = firstCol;
}
public Integer getFirstRol() {
return firstRol;
}
public void setFirstRol(Integer firstRol) {
this.firstRol = firstRol;
}
public Integer getFinalCol() {
return finalCol;
}
public void setFinalCol(Integer finalCol) {
this.finalCol = finalCol;
}
public Integer getFinalRol() {
return finalRol;
}
public void setFinalRol(Integer finalRol) {
this.finalRol = finalRol;
}
}
实现多级复杂表头的方法如下(为了方便理解,代码未做优化)
//上面其实还有建立excel等一些基础的代码没有写
//具体思路就是将表头的数据写出来形成二维数组,需要合并的单元格写一样的内容,然后再进行合并操作
String[][] oldDates = {{"1", "1", "2", "3", "3", "1"}, //多级表头的第一行
{"11", "11", "2", "21", "21", "1"}, //第二行
{"11", "11", "2", "31", "32", "1"}, //第三行
{"1", "1", "2", "31", "32", "1"}};//第四行
// 多级表头填充
for (int i = 0; i < oldDates.length; i++) {
HSSFRow row = sheet.createRow(i);
for (int j = 0; j < oldDates[i].length; j++) {
HSSFCell cell = row.createCell(j);
cell.setCellValue(oldDates[i][j]);
}
}
String key;
//利用双层map存需要合并的单元格的开始坐标和终止坐标(将一个需要合并的开始坐标和结束坐标作为一个指针,即一个UnioExcel对象)
Map<String,Map<String,UnioExcel>>mapFa=new HashMap<String, Map<String, UnioExcel>>();
for(int i=0;i<oldDates.length;i++){
for (int j=0;j<oldDates[0].length;j++){
if(j>0 && oldDates[i][j].equals(oldDates[i][j-1])){
//与左一个单元格相同
key=oldDates[i][j-1];//获取左边key
Integer tempj=j-1;
if(mapFa.containsKey(key)){
Map<String, UnioExcel> tempmap = mapFa.get(key);
//需要进行判断是否存在的指针
String tempstr=oldDates[i][j-1]+i+tempj;
if (tempmap.containsKey(tempstr)){
//判断是否与左一个相同
UnioExcel un = tempmap.get(tempstr);
un.setFinalRol(i);
un.setFinalCol(j);
//移动指针到本单元格
tempmap.put(oldDates[i][j]+i+j,un);
tempmap.remove(tempstr);
}else if(i>0){
Integer tempi=i-1;
String tempstr2=oldDates[i-1][j]+tempi+j;
//判断指针是否在同一列的上一行的位置,有则移动,没有则证明,此时需要合并的单元格还不是完整的矩形
if(tempmap.containsKey(tempstr2)){
UnioExcel unioExcel = tempmap.get(tempstr2);
unioExcel.setFinalCol(j);
unioExcel.setFinalRol(i);
//移动指针到本单元格
tempmap.put(oldDates[i][j]+i+j,unioExcel);
tempmap.remove(tempstr2);
}
}
}
}else if(i>0 && oldDates[i][j].equals(oldDates[i-1][j])) {
//判断是否和同列上一行的内容是否相同
key=oldDates[i-1][j];
Integer tempi=i-1;
String tempkeyi=oldDates[i-1][j]+tempi+j;
Map<String, UnioExcel> tempmap = mapFa.get(key);
if(tempmap.containsKey(tempkeyi)){
UnioExcel uniotemp = tempmap.get(tempkeyi);
uniotemp.setFinalRol(i);
uniotemp.setFinalCol(j);
//移动指针到本单元格
tempmap.put(oldDates[i][j]+i+j,uniotemp);
tempmap.remove(tempkeyi);
}
}else {
//与其他内容都不相同
if(mapFa.containsKey(oldDates[i][j])){
//关键部分,在不相连的单元格的地方出现了重复内容,新建一个指针
Map<String, UnioExcel> map = mapFa.get(oldDates[i][j]);
UnioExcel temunio = new UnioExcel();
temunio.setFinalCol(j);
temunio.setFinalRol(i);
temunio.setFirstRol(i);
temunio.setFirstCol(j);
map.put(oldDates[i][j]+i+j,temunio);
mapFa.put(oldDates[i][j],map);
}else {
UnioExcel temunio = new UnioExcel();
temunio.setFinalCol(j);
temunio.setFinalRol(i);
temunio.setFirstRol(i);
temunio.setFirstCol(j);
Map<String,UnioExcel> tempmap=new HashMap<String, UnioExcel>();
tempmap.put(oldDates[i][j]+i+j,temunio);
mapFa.put(oldDates[i][j],tempmap);
}
}
}
}
//遍历循环,合并单元格
Iterator<Map.Entry<String, Map<String, UnioExcel>>> it = mapFa.entrySet().iterator();
while (it.hasNext()){
Map<String, UnioExcel> value = it.next().getValue();
Iterator<Map.Entry<String, UnioExcel>> iterator = value.entrySet().iterator();
while (iterator.hasNext()){
UnioExcel value1 = iterator.next().getValue();
//合并具体的单元格
sheet.addMergedRegion(new CellRangeAddress( value1.getFirstRol() , value1.getFinalRol(), value1.getFirstCol(), value1.getFinalCol()));
}
}
//......后面就是将填充表格数据和写到本地,或者通过网页下载到本地,这些代码网上有大把资料,我就不重复了