vue 按列合并单元格

要求

使用vue对每页表格进行单元格合并,每列纵向一致的内容合并,但要参照第一列合并情况,后面的列不能跨列合并,第二列和最后一列不合并。

思路

将首列进行合并单元格计算,然后依次将后面列按照首列合并结果进行分组,然后依次给每个分组进行合并单元格计算,最后依次将该列的多个分组内容合并。
完整的html代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue Table with Merged Cells</title>
    <link
      rel="stylesheet"
      href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
    />
  </head>

  <body>
    <div id="app">
      <template>
        <div>
          <el-table
            :data="billList"  border style="width: 100%; margin-top: 20px"  :span-method="objectSpanMethod">
            <el-table-column prop="packNo" label="票据包号"> </el-table-column>
            <el-table-column prop="range" label="该列无需合并">
            </el-table-column>
            <el-table-column prop="TNo" label="编号(都一致)">
            </el-table-column>
            <el-table-column prop="company" label="公司名称">
            </el-table-column>
            <el-table-column prop="DateA" label="日期">
            </el-table-column>
            <el-table-column prop="dscntAmt" label="金额">
            </el-table-column>
            <el-table-column prop="dscntBkAreaNm" label="贴现机构">
            </el-table-column>
            <el-table-column prop="relaType" label="关联人类型">
            </el-table-column>
            <el-table-column prop="relaName" label="关联人名称">
            </el-table-column>
            <el-table-column prop="relaAcc" label="账号(不合并)">
            </el-table-column>
          </el-table>
        </div>
      </template>
    </div>
  </body>

  <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <script>
    var Main = {
      data() {
        return {
          billList: [
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "3,068.00",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2021-12-28",
              company: "一二三有限公司",
              packNo: "10477",
              range: "-",
              relaAcc: "1",
              relaName: "衣",
              relaType: "类型A",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "515,123.89",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2021-12-28",
              company: "一二三有限公司",
              packNo: "68083",
              range: "-",
              relaAcc: "2",
              relaName: "小儿",
              relaType: "类型A",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "3,111.00",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2021-12-28",
              company: "一二三有限公司",
              packNo: "10477",
              range: "-",
              relaAcc: "3",
              relaName: "小三年",
              relaType: "类型B",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "3,000.00",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2021-12-28",
              company: "一二三有限公司",
              packNo: "10477",
              range: "-",
              relaAcc: "4",
              relaName: "小似",
              relaType: "类型C",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "3,000.00",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2021-12-28",
              company: "一二三有限公司",
              packNo: "10477",
              range: "-",
              relaAcc: "5",
              relaName: "无",
              relaType: "类型C",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "515,456.89",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2021-12-28",
              company: "一二三有限公司",
              packNo: "68083",
              range: "-",
              relaAcc: "6",
              relaName: "流",
              relaType: "类型B",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "515,456.89",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2021-12-28",
              company: "一二三有限公司",
              packNo: "68083",
              range: "-",
              relaAcc: "7",
              relaName: "其",
              relaType: "类型C",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "316,133.33",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2023-2-31",
              company: "一二三有限公司",
              packNo: "07536",
              range: "-",
              relaAcc: "8",
              relaName: "八",
              relaType: "类型A",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "2,070,658.92",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2023-2-31",
              company: "一二三有限公司",
              packNo: "07536",
              range: "-",
              relaAcc: "9",
              relaName: "旧9",
              relaType: "类型A",
            },
            {
              alarmId: "6304fcd-ythy-7689-5678",
              dscntAmt: "316,133.33",
              dscntBkAreaNm: "xx机构",
              TNo: "1234567",
              DateA: "2023-2-31",
              company: "一二三有限公司",
              packNo: "07536",
              range: "-",
              relaAcc: "10",
              relaName: "市",
              relaType: "类型B",
            },
          ],
          //spanArr用于存放每一行记录的合并数
          all: [],
          packNoList: [],
        };
      },
      mounted() {
        let packNoDot = 0;
        this.billList.forEach((item, index) => {
          if (index === 0) {
            this.packNoList.push(1);
          } else {
            if (item.packNo === this.billList[index - 1].packNo) {
              this.packNoList[packNoDot] += 1;
              this.packNoList.push(0);
            } else {
              packNoDot = index;
              this.packNoList.push(1);
            }
          }
        });

        this.all[0] = this.packNoList;
        this.all[1] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

        this.all[2] = this.getGroupArray(
          this.getblankArray(this.packNoList, "TNo")
        );
        this.all[3] = this.getGroupArray(
          this.getblankArray(this.packNoList, "company")
        );
        this.all[4] = this.getGroupArray(
          this.getblankArray(this.packNoList, "DateA")
        );
        this.all[5] = this.getGroupArray(
          this.getblankArray(this.packNoList, "dscntAmt")
        );
        this.all[6] = this.getGroupArray(
          this.getblankArray(this.packNoList, "dscntBkAreaNm")
        );
        this.all[7] = this.getGroupArray(
          this.getblankArray(this.packNoList, "relaType")
        );
        this.all[8] = this.getGroupArray(
          this.getblankArray(this.packNoList, "relaName")
        );
        this.all[9] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

        for (var key in this.all) {
          console.log(key + " : " + this.all[key]);
        }
      },
      methods: {
        objectSpanMethod({ row, column, rowIndex, columnIndex }) {
          const _row = this.all[columnIndex][rowIndex];
          const _col = _row > 0 ? 1 : 0;
          //该形式为行合并
          return {
            rowspan: _row,
            colspan: _col,
          };
        },
        //分组计算每组合并,并将结果
        getGroupArray(temp) {
          var tempSub = [];
          for (var key in temp) {
            if (temp[key].length === 1) {
              tempSub.push(1);
            } else {
              var tempSubSub = [];
              var tempSubSubDot = 0;
              temp[key].forEach((item, index) => {
                if (index === 0) {
                  tempSubSub.push(1);
                } else {
                  if (item === temp[key][index - 1]) {
                    tempSubSub[tempSubSubDot] += 1;
                    tempSubSub.push(0);
                  } else {
                    tempSubSubDot = index;
                    tempSubSub.push(1);
                  }
                }
              });

              for (var key in tempSubSub) {
                tempSub.push(tempSubSub[key]);
              }
            }
          }
          return tempSub;
        },
        // 获取该列按照第一列分组后的数组
        getblankArray(packNoList, columnName) {
          var temp = [];
          for (var key in this.packNoList) {
            var subTemp = [];
            for (k = 0; k < this.packNoList[key]; k++) {
              subTemp.push("");
            }
            if (subTemp.length > 0) {
              temp.push(subTemp);
            }
          }

          var s1 = 0;
          for (var key in temp) {
            for (i = 0; i < temp[key].length; i++) {
              temp[key][i] = this.billList[s1][columnName];
              s1 = s1 + 1;
            }
          }
          return temp;
        },
      },
    };
    var Ctor = Vue.extend(Main);
    new Ctor().$mount("#app");
  </script>
</html>

效果如下:

posted @ 2023-06-03 17:56  sunday866  阅读(328)  评论(0编辑  收藏  举报