el-table 动态表格 + 动态合并多列单元格方法

2023-11-05

动态合并单元格

之前有篇文章写了 el-table 通过 :span-method 方法实现合并单元格的方法, 但是当时只写了合并第一列的, 就有小伙伴询问, 如果多列合并怎么办, 刚好最近有个项目遇到了动态表格并且要合并多列单元格, 在详细的记录一下吧

合并的原理, 见之前的博客 el-table :span-method 方法动态合并单元格

背景

这次遇到的这个表格, 比之前的更加动态了, 他的表头除了前几个和后几个固定的之外, 中间的分类也是动态的, 内容和个数都不确定
要实现的就是将类别一二三和类别一合计相同的合并

在这里插入图片描述

具体操作

先看一下服务端下发的数据结构把 服务端为了方便我们前端知道什么时候该合并, 就下发了树形的结构
其中 appealTypes 就是对应的动态表头, item 对应的就是表格的数据

在这里插入图片描述
但是如果我们通过 :span-method 来合并, 我们需要就是平铺的数据

设计结构

因为这个项目是之前的项目, 新开的功能, 所以没有用之前封装的table组件, 而是直接用的 el-table

处理数据

  1. 先将树形图的所有path遍历出来
  2. 处理我们想要的平铺格式的数据
  3. 通过平铺的数据动态的计算需要合并列的 spanArr

也就是说我们最终想要的数据是这样的, 把树形的所有路径, 都处理成一个对象放到一个数组里, 平铺开, 我们就可以通过某个字段来计算出需要合并的个数了
在这里插入图片描述
在这里插入图片描述

具体代码

<el-table
  :header-cell-style="{ background: '#EFF1F5', color: '#76829A' }"
  :data="tableData"
  height="100%"
  :span-method="spanMethod"
  border
  style="width: 100%">
  <el-table-column
    align="center"
    prop="category1"
    label="类别一">
  </el-table-column>
  <el-table-column
    align="center"
    prop="category2"
    label="类别二">
  </el-table-column>
  <el-table-column
    align="center"
    prop="category3"
    label="类别三">
  </el-table-column>
  <el-table-column
    align="center"
    prop="category4"
    label="类别四">
  </el-table-column>
  <el-table-column
    align="center"
    v-for="item in propfigData"
    :prop="item.prop"
    :label="item.label">
  </el-table-column>
  <el-table-column
    align="center"
    prop="totalNumber"
    label="类别四合计">
  </el-table-column>
  <el-table-column
    align="center"
    prop="proportion"
    label="占比">
  </el-table-column>
  <el-table-column
    align="center"
    prop="category1TotalNumber"
    label="类别一合计">
  </el-table-column>
</el-table>
export default {
  data() {
    return {
      spanArrOne: [],
      spanArrTwo: [],
      spanArrThree: [],
      propfigData: [],
      tableData: [],
    }
  },
  mounted() {
    this.configData();
  },
  methods: {
    configData() {
      this.reqGetStatisticPageList();
    },
    reqGetStatisticPageList() {
      this.$client.getStatisticPageList()
      .then(res => {
        const data = res.data;
        // 拿到所有路径
        const allPath = this.getAllPath(data.item);
        // 平铺成想要的格式
        const allTileList = this.getAllTileList(allPath, data.appealTypes);
        // 处理动态表头
        this.propfigData = data.appealTypes.map((item, idx) => {
          return {
            prop: `appealTypes${idx}`, // 自定义的prop
            label: item,
          }
        })
        this.tableData = [ ...allTileList ];
		// 根据id值来计算合并的数量, 相邻的数据如果id一样(因为已经排好序了), 就认为合并
        this.spanArrOne = this.getSpanArr(this.tableData, 'category1Id');
        this.spanArrTwo = this.getSpanArr(this.tableData, 'category2Id');
        this.spanArrThree = this.getSpanArr(this.tableData, 'category3Id');
      })
      .catch(err => {
        this.$message({
          showClose: true,
          message: err.data.message,
          type: "error",
        });
      })
    },
    getAllPath(tree) {
      const paths = [];

      for (let i = 0; i < tree.length; i++) {
        if (tree[i].list && tree[i].list.length > 0) {
          const res = this.getAllPath(tree[i].list); //如果有子节点便继续深入,直到到达叶子节点
          for (let j = 0; j < res.length; j++) {
            paths.push([tree[i], ...res[j]]); //子节点返回后将其返回的路径与自身拼接
          }
        } else {
          paths.push([tree[i]]);
        }
      }

      return paths;
    },
    getAllTileList(list) {
      let result = [];

      list.forEach((item, index) => {
        let tempArr = {};
        item[3].dataList.forEach((itm, idx) => {
          tempArr[`appealTypes${idx}`] = itm;
        })

        result.push({
          category1: item[0].name || '',
          category1Id: item[0].id + '' || '',
          category1Level: item[0].level || '',
          category2: item[1].name || '',
          category2Id: item[1].id + '' || '',
          category2Level: item[1].level || '',
          category3: item[2].name || '',
          category3Id: item[2].id + '' || '',
          category3Level: item[2].level || '',
          category4: item[3].name || '',
          category4Id: item[3].id + '' || '',
          category4Level: item[3].level || '',
          totalNumber: item[3].totalNumber,
          proportion: this.formatNumber(item[3].proportion * 100),
          category1TotalNumber: item[0].totalNumber,
          ...tempArr,
        })
      })

      return result;
    },
    formatNumber(val) {
      let result = val.toFixed(2) - 0;

      if (parseInt(result % 0.1)) {
        return result + '%';
      } else {
        return parseInt(result / 1) + '%';
      }
    },
    // 计算 数据合并 索引
    getSpanArr(data, params) {
      let arr = []; // 接收重构数组
      let spanArr = []; // 控制合并的数组
      let pos = 0; // 设置索引

      // 排序
      this.groupBy(data, params).map(v => (arr = arr.concat(v)))
      
      arr.map(res => { // 双向绑定 把源数据改为arr
        data.shift();
        data.push(res);
      })
            
      const redata = arr.map(v => v[params]);
      
      redata.reduce((old, cur, i) => {
        if (cur === old) {
          spanArr[pos] += 1;
          spanArr.push(0);
        } else {
          spanArr.push(1);
          pos = i;
        }

        return cur;
      }, {});

      return spanArr;
    },
    // 根据某个字段进行排序 输出二维数组
    groupBy(data, params) {
      const groups = {};
      data.forEach(v => {
        const group = JSON.stringify(v[params]);
        groups[group] = groups[group] || [];
        groups[group].push(v);
      })

      return Object.values(groups);
    },
    spanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0 || column.property == 'category1TotalNumber') {
        const _row = this.spanArrOne[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        }
      }
      if(columnIndex === 1) {
        const _row = this.spanArrTwo[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        }
      }
      if(columnIndex === 2) {
        const _row = this.spanArrThree[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    }
  }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

el-table 动态表格 + 动态合并多列单元格方法 的相关文章

  • 从 Internet Explorer 打印时的默认文件名

    使用 pdf 打印机打印网页 将页面另存为 pdf 时 Chrome 和 Firefox 都使用该页面
  • 在 JavaScript 中检测页面是否加载到 WKWebView 中

    如何使用 javascript 可靠地检测到页面已加载到 WKWebView 中 我希望能够检测到这些场景 iOS 和 WKWebView iOS 和 Safari not iOS 关于 UIWebView 有一个类似的问题here htt
  • 循环遍历数组并删除项目,而不中断 for 循环

    我有以下 for 循环 当我使用splice 要删除一个项目 我发现 秒 未定义 我可以检查它是否未定义 但我觉得可能有一种更优雅的方法来做到这一点 我们的愿望是简单地删除一个项目并继续 for i 0 len Auction auctio
  • 如何在javascript中动态向对象数组添加值?

    这是一个对象数组 var data label 1 value 12 label 1 value 12 label 1 value 12 label 1 value 12 我如何动态地为这些添加值 我尝试了以下代码但没有成功 var lab
  • Chrome 扩展程序可以相互通信吗?

    我正在编写一个Chrome扩展程序 并且想要实现一个接口或api 以便我将来制作的其他扩展程序可以使用它 最终的效果可能如下 分机 B 呼叫extensionA someMethod someParameters 并向分机A发送一些数据 分
  • HTML 和 标签有什么区别?

    HEAD 标签和 BODY 标签有什么区别 大多数 HTML 书籍仅 简短 提及 and 标签 但它们消失得很快 它们会影响浏览器呈现网页的方式吗 另外 它们会影响 javascript 的运行顺序吗 我的意思是 如果我里面有一个javas
  • 如何在 google.maps.event.addListener 中使用它

    以下示例有效 但是当我尝试传递参数并使用this在该功能不起作用 Working google maps event addListener markers i click showInfoWindow function showInfoW
  • jQuery UI Datepicker 奇怪的行为

    我在使用 jqueryUI 使用简单的日期选择器时遇到了一个奇怪的问题 我只想显示两个月的日历 包括上个月和当前月份 我使用了这段代码 function picker datepicker numberOfMonths 2 showCurr
  • Dialogflow Fulfillment Webhook 调用失败

    I am new to dialogflow fulfillment and I am trying to retrieve news from news API based on user questions I followed doc
  • 在自动完成上添加 jQuery 延迟

    我正在尝试为应用程序创建 jQuery 自动完成 search input on keyup function search this val autocomplete div autocomplete get ajax search se
  • Pjax动画

    我终于让 pjax 工作了 但我还有另一个问题 如何添加一些 jquery 动画 如淡出 幻灯片旧内容和淡入 幻灯片新内容 默认情况下 pjax 只是更改内容 没有任何好看的效果 任何帮助将非常感激 此致 基本上 你有一堆事件 https
  • 如何设置必须输入特定数字的字段?

    我想知道如何创建一个需要输入特定数字或文本的字段 例如 激活码 以及在输入的确认答案的情况下移动到 网页 并且在未确认的情况下移动到 另一页面 的按钮 使用必需的属性
  • 非法使用break语句; javascript

    当这个变量达到一定数量时 我希望循环停止 但我不断收到错误 未捕获的语法错误 非法的中断语句 function loop if isPlaying jet1 draw drawAllEnemies requestAnimFrame loop
  • AngularStrap 工具提示禁用我的自定义指令

    我正在尝试让 bs tooltip AngularStrap 指令与我自己的名为 checkStrength 的自定义指令一起使用 该指令检查密码的强度 单独使用这些指令中的任何一个时 它们都可以正常工作 但不能一起工作 This http
  • Angularjs : $locationProvider.hashPrefix("!") ;

    我想将网址显示为 www test com 因为我正在使用 locationProvider hashPrefix 但它显示网址为 www test com 我想 哈希之前而不是哈希之后 Thanks var app angular mod
  • 选择单选按钮时隐藏/显示 3 个文本框

    我有 2 个单选按钮 选择一个文本框时 我想显示 3 个文本框 并在选择其他文本框时隐藏它 这是代码 这是我的 2 个单选按钮
  • 将两个数字相加将它们连接起来而不是计算总和

    我将两个数字相加 但没有得到正确的值 例如 做1 2返回 12 而不是 3 我在这段代码中做错了什么 function myFunction var y document getElementById txt1 value var z do
  • 如何使用 javascript 更改文件扩展名

    有谁知道在 Javascript 中更改文件扩展名的简单方法吗 例如 我有一个带有 first docx 的变量 但我需要将其更改为 first html 这将改变字符串包含文件名 let file first docx file file
  • 使圆圈与 d3.js 上的多线匹配相同的颜色过滤?

    我有一个多线图 当按每种水果过滤时会更新 每条线条颜色对应不同的销售年份 在 的帮助下Shashank https stackoverflow com users 5569282 shashank 每个数据点线上的圆圈已添加到组中 而不是直
  • 如何通过点击复制 folium 地图上的标记位置?

    I am able to print the location of a given marker on the map using folium plugins MousePosition class GeoMap def update

随机推荐

  • ios10.3之CoreData的详细教程

    首先如果要使用CoreData可以选择在初创项目时选择添加coredata 也可以选择自己添加coredata文件 系统添加coredata后会在Appdelegate类中自动添加一个persistentContainer属性 和一个sav
  • 苹果系统与win10连接到服务器,苹果手机怎么连接win10电脑详细步骤

    使用苹果手机的朋友们你们知道苹果手机如何连接win10电脑吗 不知道的就往下看看怎么操作吧 说不定以后你可能就会用到这个方法 1 用苹果手机正品数据线连接到电脑上的 USB 端口 电脑系统会自动识别出苹果手机的内部存储器 内部存储器包括包括
  • Ai-Bot RPA自动化框架

    Ai Bot是Android Windows平台上的node js自动化框架 1 跟python的区别 跟uipaht uibot 其他框架的区别 1 VS python 相同点 Ai Bot基于node js语言的一款自动化框架 和pyt
  • 关于网络连接Network的使用

    开发一个局域网连接 代码 using UnityEngine using System Collections public class all MonoBehaviour private int serverPort public int
  • Python模拟超级大乐透随机选号

    看了一下体彩超级大乐透规则 前区号码由01 35共三十五个号码组成 后区号码由01 12共十二个号码组成 由此可以使用random模拟体彩超级大乐透随机选号 import random import time class Lottery 一
  • STM32串口:字节中断与帧中断不同导致的BUG

    文章目录 一 问题背景 1 1 硬件连接框图 1 2 玄学的BUG 1 3 帧中断触发条件 1 4 字节中断触发条件 二 解决问题 2 1 复现BUG 一个帧中断 2包数据 2 2 项目总结思考 在使用STM32F207这一款单片机调试串口
  • 利用华硕e6308_P8P67_PRO主板开发双目立体视觉问题小结

    利用华硕e6308 P8P67 PRO主板开发双目立体视觉问题小结 实验室有台组装计算机 主板是华硕e6308 P8P67 PRO 实验室要求我利用该计算机开发双目立体视觉系统 咋看上去 这块主板很猛 motherboard的图解如下 可以
  • Linux安装MySQL详细教程(YUM+离线安装)

    目录 1 Linux安装MySQL共有两种方法 2 软件包工具下载 离线 3 YUM安装步骤 4 离线安装 着重介绍 1 Linux安装MySQL共有两种方法 一是使用YUM 二是离线安装 2 软件包工具下载 离线 MySQL Downlo
  • RocketMQ基础概念

    目录 1 简介 2 架构 3 核心概念 1 简介 RocketMQ 是一款开源的分布式消息中间件 最初由阿里巴巴集团开发并开源 它旨在为分布式系统提供可靠 高性能 可扩展的消息通信能力 RocketMQ和RabbitMQ KAFKA一起并列
  • 前端常见的加密方式

    1 base64加密
  • 图像分割的衡量指标详解

    转载自 http m blog csdn net u011771047 article details 72777349 http blog csdn net u014593748 article details 71698246 fps
  • 常见的正则表达式

    目录 问题现象 问题分析 解决方法 拓展 1 手机号或座机 2 邮箱 3 中文 4 数字 5 英文 6 组合 问题现象 今天在项目中 发现有个正则表达式匹配不上导致了数据校验不通过的问题 如下 于是就产生了疑问 这个正则表达式有什么问题 校
  • ERROR: node with name "rabbit" already running on "localhost"

    解决方法1 这个问题是在我用 rabbitmq server start 启动rabbimq的时候出现的 说明此时还有一些rabbitmq的线程没有结束 可以使用ps ef grep rabbitmq查找到哪些rabbitmq线程没有结束
  • iOS(一)UI的appIcon和BrandAsset(LaunchImage)

    一 首先我们先来创建一个最简单的程序 点击之后 选择Single View Application 然后点击Next 输入工程名字 继续点Next
  • MQTT

    http baike baidu com link url ZHdQftpTVAOwtrvsd x23l8hH1Xj i3su2hbhD4yEkMlYXJnefijw0zjfnvKY9I5oLdRI8zxlfCiBhakD fGKq MQT
  • 百融云预计2022年净利润同比翻倍 金融AI平台头部效应尽显

    2月15日 百融云创 06608 HK 发布2022年正面盈利预告 预期于截至2022年12月31日止年度录得非国际财务报告准则溢利 净利润 约2 86亿元人民币至2 93亿元人民币 较去年同期增长约103 至108 公告显示 公司主业营收
  • 房价预测(基于决策树算法)

    预测波士顿房价 第一步 导入数据 在这个项目中 将使用波士顿房屋信息数据来训练和测试一个模型 并对模型的性能和预测能力进行评估 我们希望可以通过该模型实现对房屋的价值预估 提高房地产经纪人的工作效率 此项目的数据集来自kaggle原始数据
  • Pyhton考单词程序_考单词工具

    说明 首先我们需要一个单词表的文本文档像这样 只要单词中没有空格就行 然后运行程序 选择单词表文件 开始考单词 正确会提示Right 错误提示Wrong 一秒钟后清屏 代码 main py from module opfile import
  • [1049]since it exceeds Excel‘s limit of 65,530 URLS per worksheet

    文章目录 since it exceeds Excel s limit of 65 530 URLS per worksheet pandas 写入excel 转换Url链接的两种方法 since it exceeds Excel s li
  • el-table 动态表格 + 动态合并多列单元格方法

    动态合并单元格 之前有篇文章写了 el table 通过 span method 方法实现合并单元格的方法 但是当时只写了合并第一列的 就有小伙伴询问 如果多列合并怎么办 刚好最近有个项目遇到了动态表格并且要合并多列单元格 在详细的记录一下