合并多维表格

最近遇到一需求,要求数据报表正复杂样式展示,那么想到的思路就是先纵向合并,然后再横向合并,后台数据按明细倒入,前端先渲染成普通的表,然后在对表进行重构,代码如下:

/*
@param
{
oprIndex:[],需要合并的列index,index从0开始
}
*/
var deleteObjR = [],
    deleteObjC = [];

function combine(oprIndex,table){
    //转成数字数字
    var rowIndex = [],
    colIndex = [];
    var index = oprIndex.split(";");


    //纵向合并
    var cols = index[1];
    if(cols!=undefined && cols!="") {
    var col = cols.split(",");
    //转成数字数字
    for(var i= 0,len=col.length;i<len;i++) {
        colIndex.push(parseInt(col[i]));
     }
    combineCol(colIndex, table);
    chgTable(table);

    //横向合并
    var row = index[0].split(",");
    for(var i= 0,len=row.length;i<len;i++) {
        rowIndex.push(parseInt(row[i]));
    }
    var indexList = chgRowIndex(rowIndex.sort());
    if(indexList.length){
        for(var k=0,len=indexList.length; k<len; k++){
            combineRow(indexList[k],table);
        }
    }
    chgTable(table);
    }
 }

function chgRowIndex(arr){
  var tempArr = [],
      result =[],
      last=0;

  if(arr.length){
    last = arr[0];
    tempArr.push(last);
  }

  for(var k=1,len=arr.length; k<len; k++){

    if(last+1 == arr[k]){//同一组
      tempArr.push(arr[k]);
      last = arr[k];

    }else{
      tempArr.length > 1 && result.push(tempArr);

      last = arr[k];
      tempArr = [last];
    }

  }

  tempArr.length > 1 && result.push(tempArr)

  return result.length && result;
}

//横向合并时,如果被纵向合并过,调整横向合并列索引
function onCombinCol(self,indexList,table){
    var colLen  = $(table).find("thead tr").find("th").length,
        isCol = false,
        tmplen = 0,
        resultIndexList = [],
        lastIndex = 0;

    self.find("td").each(function(index){
        lastIndex = index;
        if(index==(colLen-1)){
            isCol = true;
        }
    });
    if(!isCol) {
        tmplen = colLen - 1 - lastIndex;
    }
    for(var i= 0,len=indexList.length-tmplen;i<len;i++){
        resultIndexList.push(indexList[i]);
    }

    return resultIndexList;
}

function combineRow(indexList,table){
    var table = $(table),
        max = Math.max.apply(null,indexList),
        self = null,
        begin = 0,
        count = 1,
        tmpIndexList = [],
        temp = "";

    table.find('tbody tr').each(function(index){
      self = $(this);
      begin = 0;
      count = 1;
      temp = "";
      //判断当前行,td是否被合并过
      tmpIndexList = onCombinCol(self,indexList,table);

      self.find('td').each(function(index1){
        if(tmpIndexList.indexOf(index1) == -1 || index1 > max)
          return;

        if(temp == ""){
          temp = $.trim($(this).html());
          begin = index1;
        }else{
          var current = $.trim($(this).html());
          if(temp == current){
            count++;
            if (index1 == max) {
              deleteObjR.unshift({begin:begin,count:count,row:index});
            }
          }else{

            if(count >1){
              deleteObjR.unshift({begin:begin,count:count,row:index});
            }

            temp = current;
            begin = index1;
            count = 1;
          }
        }
      });

    });
}
function combineCol(indexList,table){
    var table = $(table),
        temp = "",
        begin = 0,
        current = "",
        count = 1,
        selector = '';

    for(var j=0,len=indexList.length;j<len;j++){
        var n = indexList[j];
        selector = '.col'+ n;
        temp = "";
        begin = 0;
        current = "";
        count = 1;

        table.find(selector).each(function(index1){

            var self = $(this);

            if(index1 == 0 ){
                temp = $.trim(self.html());
                begin = index1;

            }else{
                current = $.trim(self.html());

                if(temp == current){
                    if(n!=0) {
                        var boolist = [];
                        isCombin(table, index1, n-1,boolist);
                        if(!boolist.contains(false)) {//前一列是否合并,是合并,否不合并
                            count++;
                        }else {
                            if(count > 1){
                                deleteObjC.unshift({begin:begin,count:count,col:n});
                            }
                            temp = current;
                            begin = index1;
                            count = 1;
                        }
                    }else {
                        count++;
                    }

                    if(index1 == (table.find(selector).length-1)){
                        deleteObjC.unshift({begin:begin,count:count,col:n});
                    }

                }else{

                    if(count > 1){
                        deleteObjC.unshift({begin:begin,count:count,col:n});
                    }

                    temp = current;
                    begin = index1;
                    count = 1;
                }
            }
        });

    }
}

function isCombin(table,index,n,boolist) {
    var preCurrent = '',
        current = '',
        cur = '' ,
        pre = '',
        selector = '',
        preSelector = '';

    if(boolist.contains(false) || n<0){
        return;
    }

    selector = ".col" + n +":eq("+index+")";
    preSelector = ".col" + n + ":eq("+(index-1)+")";

    pre = table.find(preSelector);
    cur = table.find(selector);

    preCurrent = $.trim(pre.html());
    current = $.trim(cur.html());
    if(preCurrent != current) {
        boolist.push(false);
    }
    //追溯到最最源头,看是否相同,不同则不能合并
    if(!boolist.contains(false)){
        isCombin(table,index,n-1,boolist);
    }
}

function chgTable(table){
    var table = $(table),
        currentObj = {},
        selector = "",
        tempCount = 0,
        tempBegin = 0,
        currentRow = null;

    for(; deleteObjR.length; ){
        currentObj = deleteObjR[0];
        tempCount = currentObj.count;
        tempBegin = currentObj.begin;
        selector = 'tbody tr:eq('+currentObj.row+')';

        currentRow = table.find(selector);

        currentRow.find('td:eq('+tempBegin+')').attr('colspan',tempCount);
        for(; tempCount > 1 ; tempCount--){
            currentRow.find('td:eq('+(tempBegin+1)+')').remove();
        }
        deleteObjR.shift(currentObj);
    }

    for(; deleteObjC.length; ){
        currentObj = deleteObjC[0];
        tempCount = currentObj.count;
        tempBegin = currentObj.begin;

        selector = '.col'+currentObj.col+':eq('+tempBegin+')';

        table.find(selector).attr('rowspan',tempCount);

        for (;tempCount > 1; tempCount--) {
            selector = '.col'+currentObj.col+':eq('+(tempBegin+1)+')';
            table.find(selector).remove();
        }
        deleteObjC.shift(currentObj);
    }
}

调用时传入参数表名和索引,表名,要合并的行索引;要合并列索引,如

var oprIndex = “0,1,2;0,1,2,3”;
combine(oprIndex,table);

结果:
原表:
原始表

重构后的表:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值