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