如何让elemengUI中的表格组件相同内容的单元格自动合并 1. 前言 2. 效果图 3. 核心代码

这两天在工作中遇到这样一个需求:将某个Excel中的数据在页面上以表格形式展示出来,并且尽量保持数据层级与Excel中一致。在原始Excel文件中,对每一行相同的数据都进行了合并,使得数据比较有层次性,而在页面表格中,也需要将相同内容的单元格进行合并。博主手头的项目使用的UI框架是elemengUIelemengUI中的表格Table组件也提供了单元格合并的方法,并且给出了示例用法,但是在示例用法中是针对静态数据的,判断是写死的。而实际情况数据往往是动态的,我们需要去判断哪两个单元格内容相同然后动态的将它们合并。经过一阵折腾终于搞定了,这就来记录一下具体的实现方法,以供参考。

2. 效果图

话不多说,先看看效果图。

原始Excel文档内容结构:
如何让elemengUI中的表格组件相同内容的单元格自动合并
1. 前言
2. 效果图
3. 核心代码

最终页面展示效果:

如何让elemengUI中的表格组件相同内容的单元格自动合并
1. 前言
2. 效果图
3. 核心代码

3. 核心代码

首先是表格结构:

<el-table
  :data="data"
  border 
  fit 
  stripe
  :span-method="cellMerge"
  highlight-current-row 
  size="small"
  style=" 100%;">
    <el-table-column prop="ruleId_1" label="指标编码" align="center" width="100"></el-table-column>
    <el-table-column prop="checkRange" label="检查范围" align="center" width="100"></el-table-column>
    <el-table-column prop="ruleId_2" label="指标编码" align="center" width="100"></el-table-column>
    <el-table-column prop="checkContent" label="检查内容" align="center" width="100"></el-table-column>
    <el-table-column prop="ruleId_3" label="指标编码" align="center" width="120"></el-table-column>
    <el-table-column prop="checkItem" label="检查项" align="center" width="300"></el-table-column>
    <el-table-column prop="ruleId_4" label="指标编码" align="center" width="200"></el-table-column>
    <el-table-column prop="checkPoint" label="检查要点" align="left"  header-align="center"></el-table-column>
</el-table>

数据data:

export default {
  name:'levelProtect',
  data () {
    return {
      data:[],     //表格数据
      spanArr: [],//二维数组,用于存放单元格合并规则
      position: 0,//用于存储相同项的开始index
    }
  }

方法methods:

  created() {
    this.getTableData()
  },
  methods:{
    // 从后端获取表格数据
    getTableData() {
        let para = {};
        axios({
            method: "post",
            url: "...",
            data: para
        })
         .then(res => {
            this.data = res.data || [];
            this.rowspan(0,'ruleId_1');
            this.rowspan(1,'checkRange');
            this.rowspan(2,'ruleId_2');
            this.rowspan(3,'checkContent');
            this.rowspan(4,'ruleId_3');
            this.rowspan(5,'checkItem');
            this.rowspan(6,'ruleId_4');
            this.rowspan(7,'checkPoint');
        })
        .catch(err => {});
    },
    rowspan(idx, prop) {
      this.unit.spanArr[idx] = [];
      this.unit.position = 0; 
      this.unit.data.forEach((item,index) => {
        if( index === 0){
          this.unit.spanArr[idx].push(1);
          this.unit.position = 0;
        }else{
          if(this.unit.data[index][prop] === this.unit.data[index-1][prop] ){
            this.unit.spanArr[idx][this.unit.position] += 1;//有相同项
            this.unit.spanArr[idx].push(0); // 名称相同后往数组里面加一项0
          }else{
            this.unit.spanArr[idx].push(1);//同列的前后两行单元格不相同
            this.unit.position = index;
          }
        }
      })
    },
    //表格单元格合并
    cellMerge({ row, column, rowIndex, columnIndex }) {
      for(let i = 0; i<this.spanArr.length; i++) {
        if(columnIndex === i){
          const _row = this.unit.spanArr[i][rowIndex];
          const _col = _row>0 ? 1 : 0;
          // console.log('第'+rowIndex+'行','第'+i+'列','rowspan:'+_row,'colspan:'+_col)
          return {
            rowspan: _row,
            colspan: _col
          }
        }
      }
    }
  }

代码说明:

  • 在组件加载时,调用getTableData方法从后端拉取表格数据;
  • 得到表格数据后,我们把需要相同内容单元格合并的列通过调用this.rowspan(0,'ruleId_1');,得到的spanArr二维数组表示该列所需要合并的行数;
  • cellMerge就是传给el-table合并行或列的计算方法

如果还是没有看明白,那就直接运行demo看看吧,demo猛戳这里!!!

(完)