遇到过好几次需要对表格进行合并的情况了,写了个方法对这种情况的数据进行处理。

需求:

数据处理代码

// 原始数据
var list = [
  {
    "companyName":"测试公司2",
    "createByName":"系统管理员",
    "province":"四川省",
    "teamSize":1,
    "children":[
      {
        "platform":"头条",
        "agent":"湖北今日头条代理商",
        "children":[
          {
            "form":"表单",
            "children":[
              {
                "industry":"常规",
                "rebate":0.15
              },
              {
                "industry":"特殊",
                "rebate":9
              }
            ]
          },
          {
            "form":"下载",
            "children":[
              {
                "industry":"常规",
                "rebate":0.8
              }
            ]
          },
          {
            "form":"引流",
            "children":[
              {
                "industry":"常规",
                "rebate":0.5
              },
              {
                "industry":"常规1",
                "rebate":"0.2 - 0.5"
              }
            ]
          }
        ]
      },
      {
        "platform":"百度",
        "agent":"渠道商",
        "children":[
          {
            "form":"加粉",
            "children":[
              {
                "industry":"行业1",
                "rebate":0.15
              }
            ]
          },
          {
            "form":"斗金",
            "children":[
              {
                "industry":"行业1",
                "rebate":0.8
              },
              {
                "industry":"行业2",
                "rebate":0.2
              }
            ]
          }
        ]
      }
    ]
  }
]

// 计算合并行
function handle(list) {
  var num = 0;
  for (var i = 0; i < list.length; i++) {
    if (list[i].children && list[i].children.length) {
      var temp = handle(list[i].children);
      list[i].childrenRowNum = temp;
      num += temp;
    } else {
      num++;
    }
  }

  return num;
}

// 拆分数据
function handle1(list, pObj, allKeyObj, dataArr) {
  if (!pObj) pObj = {};
  if (!allKeyObj) allKeyObj = {};
  dataArr = JSON.parse(JSON.stringify(dataArr || []));

  for (var i = 0; i < list.length; i++) {
    for (var key in allKeyObj) delete list[i][key];

    var rowspan = list[i].childrenRowNum || 1;
    for (var key in list[i]) {
      if (key != 'childrenRowNum') {
        list[i][key] = {
          value: list[i][key],
          rowspan: rowspan
        }
      }
    }
    delete list[i].childrenRowNum;

    if (list[i].children && list[i].children.value.length) {
      var item = JSON.parse(JSON.stringify(list[i]));
      delete item.children;
      if (i) {
        dataArr = handle1(list[i].children.value, {...item}, {...allKeyObj, ...item}, dataArr)
      } else {
        dataArr = handle1(list[i].children.value, {...item, ...pObj}, {...allKeyObj, ...item}, dataArr)
      }
    } else {
      if (i) {
        dataArr.push(list[i]);
      } else {
        dataArr.push({...list[i], ...pObj})
      }
    }
  }

  return dataArr;
}

handle(list);
var dataArr = handle1(list); 

vue模板代码

<table>
  <tr>
    <th>地区</th>
    <th>公司</th>
    <th>平台</th>
    <th>形式</th>
    <th>行业</th>
    <th>返点</th>
    <th>代理性质</th>
    <th>联系人</th>
    <th>团队数</th>
  </tr>
  <tr v-for="item in dataArr">
    <td v-if="item.province" :rowspan="item.province.rowspan">{{ item.province.value }}</td>
    <td v-if="item.companyName" :rowspan="item.companyName.rowspan">{{ item.companyName.value }}</td>
    <td v-if="item.platform" :rowspan="item.platform.rowspan">{{ item.platform.value }}</td>
    <td v-if="item.form" :rowspan="item.form.rowspan">{{ item.form.value }}</td>
    <td v-if="item.industry" :rowspan="item.industry.rowspan">{{ item.industry.value }}</td>
    <td v-if="item.rebate" :rowspan="item.rebate.rowspan">{{ item.rebate.value }}</td>
    <td v-if="item.agent" :rowspan="item.agent.rowspan">{{ item.agent.value }}</td>
    <td v-if="item.createByName" :rowspan="item.createByName.rowspan">{{ item.createByName.value }}</td>
    <td v-if="item.teamSize" :rowspan="item.teamSize.rowspan">{{ item.teamSize.value }}</td>
  </tr>
</table> 

需求:

数据处理代码

// 原始数据
var dataList = [{...}, {...}, {...}, ...];
var header = [
	{name: '淘金号'},
	{name: '质检人'},
	{name: '客服姓名'},
	{name: '质检日期'},
	{name: '项目主管'},
	{name: '商家名称'},
	{name: '店铺ID'},
	{name: '服务日期'},
	{
		name: '姓名',
		children: [
			{name: '用户昵称'},
			{name: '真实姓名'},
		]
	},
	{
		name: '服务态度',
		children: [
			{name: '是否用户先挂电话'},
			{
				name: '有无开头和结束语',
				children: [
					{name: '开头语'},
					{
						name: '结束语',
						children: [
							{name: '结束1'},
							{name: '结束2'},
						]
					},
				]
			},
			{name: '用户评分'},
		]
	},
	{
		name: '处理效率',
		children: [
			{
				name: '首次响应时间'
			},
			{
				name: '处理时长',
				children: [
					{name: '问题难度'},
					{name: '时长'},
				]
			},
		]
	},
	{
		name: '加分项',
		children: [
			{name: '4.2'},
		]
	},
	{name: '质检得分'},
	{name: '备注'},
	{name: '扣罚类别'},
	{name: '扣罚金额'},
	{name: '商家平台'},
];

// 计算列的合并数
function colspanFun(arr) {
	var totalObj = {
		colspan: 0,
		keyList: []
	}

	for (var i = 0; i < arr.length; i++) {
		var item = arr[i];
		var obj = {
			colspan: 1,
			keyList: [item]
		}
		if(item.children && item.children.length) {
			obj = colspanFun(item.children);
		}
		item.colspan = obj.colspan;

		totalObj.colspan += obj.colspan;
		totalObj.keyList = [...totalObj.keyList, ...obj.keyList]
	}
	return totalObj;
}

// 分割为多行数据
function rowspanFun(arr, rowIndex, list) {
	if(!rowIndex) rowIndex = 0;
	if(!list) list = [];
	if(!list[rowIndex]) list[rowIndex] = [];
	var rowArr = list[rowIndex];

	for (var i = 0; i < arr.length; i++) {
		var item = arr[i];
		rowArr.push(item);
		if(item.children && item.children.length) {
			rowspanFun(item.children, rowIndex + 1, list);
		}
	}

	return list;
}

// 计算每个格子行合并数
function rowHandle(list) {
	var maxRow = list.length;
	for (var i = 0; i < list.length; i++) {
		var rowArr = list[i];
		for (var j = 0; j < rowArr.length; j++) {
			var item = rowArr[j];
			if(item.children && item.children.length) {
				item.rowspan = 1;
			} else {
				item.rowspan = maxRow - i;
			}
		}
	}
}

var {keyList} = colspanFun(header);
var dataArr = rowspanFun(header);
rowHandle(dataArr);

vue模板代码

<table>
  <tr v-for="rowArr in dataArr">
    <th v-for="item in rowArr" :rowspan="item.rowspan" :colspan="item.colspan">{{ item.name }}</td>
  </tr>
  <tr v-for="row in dataList">
    <td v-for="fieldObj in keyList">{{ row[fieldObj.name] }}</td>
  </tr>
</table>