vue3实现table第一列第二列合并相同行

原理不难,晚上找了一堆全是废话,自己造了一个:
1、模拟数据为 JSON格式;
2、需转为二维数组;
3、控制表格合并,删除合并项。

<template>
  <div>
    <table>
      <tbody>
        <tr>
          <th
            colspan="3"
            class="th-box"
            style="text-align: left; color: #ffc000"
          >
            三、汇总
          </th>
        </tr>
        <tr>
          <th class="big-th">物料名称</th>
          <th class="big-th">阶段</th>
          <th class="big-th">物料类型</th>
          <th class="big-th">需求数量</th>
          <th class="big-th">单位</th>
        </tr>
        <tr v-for="(item, index) in listTotal" :key="index">
          <td v-if="item.show1" :rowspan="item.rowspan1">{{ item.data[0] }}</td>
          <td v-if="item.show2" :rowspan="item.rowspan2">{{ item.data[1] }}</td>
          <!-- <td>{{ item.data[1] }}</td> -->
          <td>{{ item.data[2] }}</td>
          <td>{{ item.data[3] }}</td>
          <td>{{ item.data[4] }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup>
  import { ref, onMounted } from "vue";

  onMounted(() => {
    transformListTotalFn(objJson);
  });

  // 模拟数据
  const objJson = {
	  MB: {
	    TR4: {
	      PCBA: {
	        panel: 1,
	      },
	    },
	    总计: {
	      PCBA: {
	        panel: 1,
	      },
	    },
	  },
	  CPU: {
	    TR6: {
	      其他原材料: {
	        pcs: 3,
	      },
	    },
	    总计: {
	      其他原材料: {
	        pcs: 3,
	      },
	    },
	  },
	  KTV: {
	    TR6: {
	      PCBA: {
	        pcs: 6,
	      },
	    },
	    总计: {
	      PCBA: {
	        pcs: 6,
	      },
	    },
	  },
	  kfc: {
	    TR5: {
	      PCBA: {
	        pcs: 4,
	      },
	    },
	    TR6: {
	      PCBA: {
	        pcs: 3,
	      },
	      其他原材料: {
	        pcs: 10,
	      },
	    },
	    总计:{
	      PCBA: {
	        pcs: 7,
	      },
	      其他原材料: {
	        pcs: 10,
	      },
	    }
	  },
	};

  const listTotal = ref([]);
  // const columns = ['card_name', 'stage', 'card_type', 'num', 'unit'];
  function transformListTotalFn(_obj) {
    let _arr = [];
    for (let k in _obj) {
      for (let l in _obj[k]) {
        for (let m in _obj[k][l]) {
          for (let n in _obj[k][l][m]) {
            // let item = {
            //   card_name: k,
            //   stage: l,
            //   card_type: m,
            //   num: _obj[k][l][m][n],
            //   unit: n,
            // };
            let item = [k, l, m, _obj[k][l][m][n], n];
            _arr.push(item);
          }
        }
      }
    }
    console.log("表格列表:", _arr);
    const _m1 = getMergeArrFn(_arr, 0);
    const _m2 = getMergeArrFn(_arr, 1);
    console.log("m1 m2:::::", _m1, _m2);
    let _arr2 = [];
    _arr.map((v, i) => {
      let _obj = {
        show1: true,
        show2: true,
        rowspan1: 1,
        rowspan2: 1,
        data: v,
      };
      _m1.map((v2) => {
        if (i > v2[0] && i <= v2[1]) {
          _obj.show1 = false;
        }
        if (i == v2[0]) {
          _obj.rowspan1 = v2[1] - v2[0] + 1;
        }
      });
      _m2.map((v2) => {
        if (i > v2[0] && i <= v2[1]) {
          _obj.show2 = false;
        }
        if (i == v2[0]) {
          // console.log(i, v2)
          _obj.rowspan2 = v2[1] - v2[0] + 1;
        }
      });
      _arr2.push(_obj);
    });
    console.log("处理的表格列表:", _arr2);
    listTotal.value = _arr2;
  }

  //
  /**
 * 生成合并项 位置
 * @param { Array } _arr 二维数组 
 * @param { Number | String } key 对比位置
 */
function getMergeArrFn (_arr, key = 0) {
  let arrDiff = [];
  let idxS = 0; // 合并起始位置
  let idxMerge = 0; // 合并的个数
  let _len2 = _arr.length;
  for (let i = 1; i < _len2; i++) {
    console.log(_arr[i][key])
    if (_arr[i][key] === _arr[i - 1][key]) {
      idxMerge += 1;
      if (i === _len2 - 1) {
        arrDiff.push([idxS, i]);
      }
    } else {
      if (idxMerge > 0) {
        arrDiff.push([idxS, idxS + idxMerge]);
        idxMerge = 0;
      }
      idxS = i;
    }
  }
  return arrDiff
}
</script>

二、表格数据(二维数组转JSON对象)

// 模拟数据
const inputArray =[
    ["MB", "TR4",  "PCBA", 1,  "panel"],
    ["CPU", "TR6",  "其他原材料",  3,  "pcs" ],
    ["KTV", "TR6", "PCBA", 6, "pcs"],
    ["kfc",  "TR5",   "PCBA", 4,  "pcs"],
    [ "kfc",  "TR6",  "PCBA", 3, "pcs" ],
    ["kfc", "TR6",  "其他原材料", 10,  "pcs"]
]; 

/**
 * 表格转 JSON对象
 * @param { Array } array 二维数组
 */
const convertArrayToObject = (array) => {
  return array.reduce((result, [one, two, three, num, unit]) => {
    if (!result[one]) {
      result[one] = {};
    }
    if (!result[one][two]) {
      result[one][two] = {};
    }
    if (!result[one][two][three]) {
      result[one][two][three] = {};
    }
    // 将数量转换为浮点数  
    const numFloat = Number(num);
    // 设置单位的值  
    result[one][two][three][unit] = isNaN(numFloat) ? num : numFloat;
    return result;
  }, {});
};

  const outputObject = convertArrayToObject(inputArray );
  console.log(outputObject);


/** 增加总计 */
function transformAddTotalFn (_obj) {
  for (let k in _obj) {
    _obj[k]['总计'] = {}
    for (let l in _obj[k]) {
      if (l === '总计') continue;
      for (let m in _obj[k][l]) {
        if (!_obj[k]['总计'][m]) {
          _obj[k]['总计'][m] = {};
        }
        for (let n in _obj[k][l][m]) {
          // console.log(_obj[k]['总计'][m])
          // 判断是否存在
          if (Object.prototype.hasOwnProperty.call(_obj[k]['总计'][m], n)) {
            _obj[k]['总计'][m][n] += _obj[k][l][m][n];
          } else {
            _obj[k]['总计'][m][n] = _obj[k][l][m][n];
          }
        }
      }
    }
  }
  return _obj;
}
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值