element中table实现多表头动态数据/合并行/合并列/导出excel功能实现

参考地址:https://blog.csdn.net/hefeng6500/article/details/82778680?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
实现如图功能:
在这里插入图片描述
html: 其中:span-method="dataArraySpanMethod" 是合并列需要的属性

<template>
  <div>
    <el-table class="crmonepage-hello" ref="tabled" :data="list" style="width: 100%" :span-method="dataArraySpanMethod">
      <el-table-column
        v-for="(col,index) in cols"
        :label="col.label"
        :key="index"
        :width="col.width || null"
        :prop="col.prop"
      >
        <el-table-column
          v-for="(props, propsindex) in col.propsChildren"
          :label="props.label"
          :key="propsindex"
          :width="props.width || null"
          :prop="props.prop"
        ></el-table-column>
      </el-table-column>
    </el-table>
    <button @click="exportExcel"></button>
  </div>
</template>

数据格式:

  data() {
    return {
      list: [
        {aQty: "1",bQty: "8",cQty: "2",dQty: "-1",eQty: "11",brand: "一点点",brand2: "列合并测试",brand3: "测试"},
        {aQty: "3",bQty: "2",cQty: "12",dQty: "-3",eQty: "121",brand: "一点点",brand2: "列合并测试",brand3: "测试"},
        {aQty: "13",bQty: "2",cQty: "24",dQty: "-1",eQty: "11",brand: "点点",brand2: "行合并",brand3: "测试"}
      ], // 数据
      cols: [
        {prop: "brand",label: "面包店", width: null},
        {prop: "brand2",label: "列合并测试",width: null},
        {prop: "brand3",label: "测试面包店",width: null},
        {prop: "Production",label: "饮料",width: null,propsChildren: [{prop: "aQty",label: "西瓜汁",width: null,}]},
        {prop: "market",label: "食物数量",width: null,propsChildren: [
            {prop: "bQty",label: "菜包",width: 150},
            {prop: "cQty",label: "肉包",width: 150},
            {prop: "dQty",label: "苹果",width: 150},
            {prop: "eQty",label: "西瓜",width: 150}]
         },
      ], // 网格列
      // 合并列数数组
      spanArr: [],
      spanArr2: [],
      pos: 0,
      pos2: 0,
      dataArraySpanMethod:function(){}  // 因为dataArraySpanMethod属性定义的是函数
    };
  },
      
 mounted() {
    this.merge();
  },
  methods: {
    // 判断需要合并的重复项  获得其所在数组下标
    getSpanArr(data) {
      this.spanArr = [];
      this.spanArr2 = [];
      for (var i = 0; i < data.length; i++) {
        if (i === 0) {
          this.spanArr.push(1);
          this.spanArr2.push(1);
          this.pos = 0;
          this.pos2 = 0;
        } else {
          if (data[i].brand === data[i - 1].brand) {  // 判断面包店
            this.spanArr[this.pos] += 1;
            this.spanArr.push(0);
          } else {
            this.spanArr.push(1);
            this.pos = i;
          }
          //
          if (data[i].brand2 === data[i - 1].brand2) { // 判断列合并测试
            this.spanArr2[this.pos2] += 1;
            this.spanArr2.push(0);
          } else {
            this.spanArr2.push(1);
            this.pos2 = i;
          }
        }
      }
    },
    merge() {
      const that=this
      this.getSpanArr(this.list);
      that.dataArraySpanMethod = function({row,column,rowIndex,columnIndex}) {
        // 列合并
        if (columnIndex === 0) { //表示下标为0的列数
          const _row = that.spanArr[rowIndex];
          const _col = _row > 0 ? 1 : 0;
          // 行合并
          if(rowIndex==2){   //表示下标为0的列数,为2的行数 向右合并两格
            return{rowspan:1,colspan:2}
          }
          // 列合并
          return {
            rowspan: _row,
            colspan: _col
          };
        }
        if (columnIndex === 1) {  // 表示下标为1的列数
          const _row = that.spanArr2[rowIndex];
          const _col = _row > 0 ? 1 : 0;
           if(rowIndex==2){   //表示下标为1的列数,为2的行数 解决串行问题 !!注意一定要添加,如果不添加则如图一显示
            return{rowspan:0,colspan:0}
          }
          // 合并列
          return {
            rowspan: _row,
            colspan: _col
          };
        }
      };
    },
   

图一:
在这里插入图片描述
如果是组件之间使用合并属性 dataArraySpanMethod
则需要在引入的组件中定义ref 例:
that.$refs.tabled.dataArraySpanMethod = function({row,column,rowIndex,columnIndex}) {}

导出:
引入以下依赖

import FileSaver from "file-saver";
import XLSX from "xlsx";
import Vue from "vue";
 // 导出
    exportExcel() {
      let str = "面包店测试.xlsx";//导出文档名称
      // 判断要导出的节点中是否有fixed的表格,如果有,转换excel时先将该dom移除,然后append回去  解决重复数据问题
      var fix = document.querySelector(".el-table__fixed");
      var wb;
      if (fix) {
        wb = XLSX.utils.table_to_book(
        //导出表格类名
          document.querySelectorAll(".crmonepage-hello")[0].removeChild(fix)
        );
        document.querySelectorAll(".crmonepage-hello")[0].appendChild(fix);
      } else {
        wb = XLSX.utils.table_to_book(
          document.querySelectorAll(".crmonepage-hello")[0]
        );
      }
      var wbout = XLSX.write(wb, {
        bookType: "xlsx",
        bookSST: true,
        type: "array"
      });
      try {
        FileSaver.saveAs(
          new Blob([wbout], { type: "application/octet-stream" }),
          str
        );
      } catch (e) {
        if (typeof console !== "undefined") console.log(e, wbout);
      }
      return wbout;
    }
  }

你可能感兴趣的:(遇到的问题,element,vue,vue,javascript,js)