一.js版:
示例:
var tb = document.getElementById("testtable");
autoRowSpan(tb,0,0,tb.rows.length-1,true,3);
//效果如下:
autoRowSpan(tb,0,0,tb.rows.length-1,false,null);
autoRowSpan(tb,1,0,tb.rows.length-1,false,null);
autoRowSpan(tb,2,0,tb.rows.length-1,false,null);
//效果如下:
autoRowSpan(tb,2,0,tb.rows.length-1,true,0);
//效果如下:
//付详细代码:
/**
*tbDom table 元素,tbody也可以
*colIndex 合并的列索引
*startRow 起始行号
*endRow 终止行号
*isForward 是否递进合并其他列
*forwardToIndex 递进至第几列
*/
function autoRowSpan(tbDom,colIndex,startRow,endRow,isForward,forwardToIndex){
alert(colIndex+"|"+startRow+"|"+ endRow +"|"+ isForward +"|"+forwardToIndex );
var rowspanIdx = startRow;//
var pos = 1;
var compareValue = null;
for(var i=startRow; i<=endRow; ++i){
if(i == startRow){//取得起始行数据
compareValue = tbDom.rows[i].cells[colIndex].innerText;
}else{//
var tmpValue = tbDom.rows[i].cells[colIndex].innerText;
if(compareValue == tmpValue){//与起始行单元格相同,则隐藏当前单元格
pos++;
tbDom.rows[i].cells[colIndex].style.display="none";
}else{与起始行单元格不同,则设置起始行rowspan,并更新变量数据
compareValue = tmpValue;
if(pos>1){//存在相同单元格
tbDom.rows[rowspanIdx].cells[colIndex].rowSpan = pos;
//是否递进合并下一列
if(isForward){
var nextColIndex = colIndex;
var tmpStartRow = rowspanIdx;
var tmpEndRow = rowspanIdx + pos -1 ;
if(colIndex < forwardToIndex)nextColIndex++;
if(colIndex > forwardToIndex)nextColIndex--;
if(colIndex == forwardToIndex)return;
doRowspanTask(autoRowSpan,tbDom,nextColIndex,tmpStartRow,tmpEndRow,isForward,forwardToIndex);
}
}
pos = 1;
rowspanIdx = i;
}
}
}
if(pos>1){
tbDom.rows[rowspanIdx].cells[colIndex].rowSpan = pos;
//是否递进合并下一列
if(isForward){
var nextColIndex = colIndex;
var tmpStartRow = rowspanIdx;
var tmpEndRow = rowspanIdx + pos - 1 ;
if(colIndex < forwardToIndex)nextColIndex++;
if(colIndex > forwardToIndex)nextColIndex--;
if(colIndex == forwardToIndex)return;
doRowspanTask(autoRowSpan,tbDom,nextColIndex,tmpStartRow,tmpEndRow,isForward,forwardToIndex);
}
pos =1;
rowspanIdx = rowspanIdx + pos -1;
}
}
//防止递归过多导致内存溢出
function doRowspanTask(func){
if(typeof func =='function'){
var args = Array.prototype.slice.call(arguments,1);
var f = function(){
func.apply(null,args);
}
return window.setTimeout(f,0);
}
}
java 版:
excel效果同js一样,这里就直接贴代码:
/**
*
* @param sheet
* @param colIdx 合并的列
* @param startRow 起始行
* @param stopRow 结束行
* @param isForward 是否递进合并其它列
* @param forwardToColIdx 递进到的列
*/
public void mergeRowCell(HSSFSheet sheet,int colIdx,int startRow,int stopRow ,boolean isForward,int forwardToColIdx){
String compareValue = null;
int beginRow = startRow;
int endRow = startRow;
for(int i=startRow;i<=stopRow; ++i){
String value = sheet.getRow(i).getCell(colIdx).getRichStringCellValue()==null ? "":sheet.getRow(i).getCell(colIdx).getRichStringCellValue().toString();
if(i == startRow){
compareValue = value;
}else{
if(compareValue.equals(value)){//相同,则设置重复的值为空
sheet.getRow(i).getCell(colIdx).setCellValue("");
endRow = i;
}else {//不同,则合并之前相同的单元格
if(beginRow < endRow){
sheet.addMergedRegion(new CellRangeAddress(beginRow,endRow,colIdx,colIdx));
if(isForward){//递进合并下一列
int nextColIndex = colIdx;
if(colIdx < forwardToColIdx){
nextColIndex ++;
}else if(colIdx > forwardToColIdx){
nextColIndex --;
}else{
return;
}
mergeRowCell(sheet, nextColIndex, beginRow, endRow, isForward, forwardToColIdx);
}
}
compareValue = value;
beginRow = i;
endRow = i;
}
}
}
if(beginRow < endRow){
sheet.addMergedRegion(new CellRangeAddress(beginRow,endRow,colIdx,colIdx));
if(isForward){//递进合并下一列
int nextColIndex = colIdx;
if(colIdx < forwardToColIdx){
nextColIndex ++;
}else if(colIdx > forwardToColIdx){
nextColIndex --;
}else{
return;
}
mergeRowCell(sheet, nextColIndex, beginRow, endRow, isForward, forwardToColIdx);
}
}
}