一、首先按需求举个例子:

在利用vue的一些框架开发中(比如ruoyi),有时会遇见这样需要一对多对多显示的表格(如下图),按照相同项合并多余的行。看到这如果和你遇见的问题相似那就步入正题

二、前端的设计

<h2>动态合并表格<h2>
  <el-table
  :data="tableData"
  style="width: 100%"
  :span-method="objectSpanMethod"
  border
  >
<!--遍历表-->
    <el-table-column
      :prop="item.prop"
      :label="item.label"
      v-for="(item, index) in tableHeader"<!--按设定的表头-->
      :key="index"
    ></el-table-column>
  </el-table>
</el-dialog>

讲解中不以具体某些数据举例,统一用tableDatap[]数据对象数组表示需要遍历的数据

<script>
export default {
  name: "MultiRowMergeTable",
  data() {
    this.spanMap = {};
    this.mergedColumns = ["examineName","examineProject"]
    return {
      tableHeader: [
        {
          prop: "examineName",
          label: "检查表",
        },
        {
          prop: "examineProject",
          label: "检查项目",
        },
        {
          prop: "examineWord",
          label: "检查内容",
        },
        {
          prop: "remark",
          label: "备注",
        }
      ],
      tableData: []
    }
  },
  created() {
    this.getList();//进入页面时调用getList()获取tableData[]数据
  },
  methods: {
    //具体获取数据方法因需求而异
    getList() {
      listExamineTableData(this.queryParams).then(response => {
        this.tableData = response.data;
        this.getSpanArr(this.tableData);
      });
    },
    getSpanArr(data) {
      for (var i = 0; i < data.length; i++) {
        if (i === 0) {
          this.mergedColumns.forEach(column => {
            this.spanMap[column] = {
              spanArr: [1],
              pos: 0
            }
          })
        } else {
          this.mergedColumns.forEach(column => {
            if (data[i][column] === data[i - 1][column]) {
              this.spanMap[column].spanArr[this.spanMap[column].pos] += 1;
              this.spanMap[column].spanArr.push(0)
            } else {
              this.spanMap[column].spanArr.push(1);
              this.spanMap[column].pos = i;
            }
          })
        }
      }
    },
    objectSpanMethod({ column, rowIndex }) {
      if (this.spanMap[column.property]) {
        const _row = this.spanMap[column.property].spanArr[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    }
  }
}
</script>

到这里前端的开发就已经完成了,只要getSpanArr(data) 和objectSpanMethod({ column, rowIndex })方法正常无错的带入就不会有太大问题。

三、后端数据说明及常见问题

后端代码就正常编写Controller类,Service类,Mapper类

常见并经常忽略Bug的来了

数据库以下列形式表示时

前端会显示为:

原因就是前端合并单元格的方法中只合并连续相同的数据行 ,由于数据添加顺序、时间等因素不同的影响无法保证相同连续。

所以我们在查询数据库的时候需要运用SQL语句中的自定义排序查询,运用自定义排序就需要新建一个与之对应的数据字典。如下简单的一个表project_dict

在对应的mybatis配置文件Mapper.xml中写以下查询语句

<select id="selectExamineProjectNotNullList" parameterType="String" resultMap="SysExamineProjectResult">
    select *
    from sys_examine_project
    inner  join project_dict p on p.examine_project = sys_examine_project.examine_project 
and sys_examine_project.examine_name = #{examineName}  
    order by p.id
</select>

其他and的条件因人而异但是这句连接数据字典的条件一定要有

inner  join project_dict p on p.examine_project = sys_examine_project.examine_project

查询结果如下:

综上,就可以得到一个心怡的依靠动态数据合并单元格表格了

Logo

前往低代码交流专区

更多推荐