vue2+antd实现表格合并;excel效果

效果图

一、html

javascript 复制代码
<template>
  <div>
    <a-table :columns="columns" :dataSource="dataSource" rowKey="id" :pagination="false" bordered>
      
        <template slot="content1" slot-scope="text">
          {{text}}
        </template> </a-table>
  </div>
</template>

二、js

javascript 复制代码
export default {

  data () {
   
    return {
      sortLevel: ['date'],
      columns: [
        {
          title: '日期',
          align: 'center',
          dataIndex: 'date',
          key: 'date',
          customRender: this.dateRender,

        },
        {
          title: '内容',
          colSpan: 2,
          dataIndex: 'content',
           scopedSlots: { customRender: 'content1' },
       
        },
        {
          title: '内容',
          colSpan: 0,
          dataIndex: 'content2',
          // customRender: renderContent,
        },
    
      ],
      datas: [
        {
          id: 1,
          content: '123',
          content2: 'qqw',
          date: '周一'

        },
        {
          id: 2,
          content: '123',
          content2: 'qwqw',

          date: '周二'

        },
        {
          id: 3,
          content: '123',
          content2: 'wewe',

          date: '周一'

        },
        ,
        {
          id: 42,
          content: '12332',
          content2: 'sad',

          date: '周三'

        },
        ,
        {
          id: 52,
          content: '1223',
          content2: 'asdasd',

          date: '周一'

        }
      ],
      dataSource: []
    }
  },
  mounted () {
    this.dataSource = this.convertData(this.datas)
    console.log('   this.dataSource : ', this.dataSource);
  },
  methods: {
    dateRender (value, row, index) {
      return {
        children: value,
        attrs: {
          rowSpan: row.dateRowSpan
        },
      };
    },
    // 获取需要合并数据的rowSpan
    convertData (arr, levelIndex = 0) {
      const levelKey = this.sortLevel
      const key = levelKey[levelIndex]

      // 根据不同维度重新整合数据
      let groupObj = this.groupBy(arr, key) || {};
      Object.keys(groupObj).forEach(groupKey => {
        if (levelIndex < levelKey.length - 1) {
          groupObj[groupKey] = this.convertData(groupObj[groupKey], levelIndex + 1)
        }
        // 计算rowSpan
        groupObj[groupKey].forEach((item, index, arr) => {
          item[`${key}RowSpan`] = index === 0 ? arr.length : 0
        })
      })

      return Object.values(groupObj).flat()
    },
    // 根据属性分组
    groupBy (arr = [], key) {
      let obj = {}
      arr.forEach(item => {
        const val = item[key]
        if (!obj[val]) {
          obj[val] = []
        }
        obj[val].push(item)
      })

      return obj
    },
  },
}

三、完整代码

javascript 复制代码
<template>
  <div>
    <a-table :columns="columns" :dataSource="dataSource" rowKey="id" :pagination="false" bordered>
      </a-table>
  </div>
</template>

<script>


export default {

  data () {

    const renderContent = (value, row, index) => {
      const obj = {
        children: value,
        attrs: {},
      };
      if (index === 3) {
        obj.attrs.colSpan = 0;
      }
      return obj;
    };
    return {
      sortLevel: ['date'],
      columns: [
        {
          title: '日期',
          align: 'center',
          dataIndex: 'date',
          key: 'date',
          customRender: this.dateRender,

        },
        {
          title: '内容',
          colSpan: 2,
          dataIndex: 'content',
        
        },
        {
          title: '内容',
          colSpan: 0,
          dataIndex: 'content2',
          // customRender: renderContent,
        },
    
      ],
      datas: [
        {
          id: 1,
          content: '123',
          content2: 'qqw',
          date: '周一'

        },
        {
          id: 2,
          content: '123',
          content2: 'qwqw',

          date: '周二'

        },
        {
          id: 3,
          content: '123',
          content2: 'wewe',

          date: '周一'

        },
        ,
        {
          id: 42,
          content: '12332',
          content2: 'sad',

          date: '周三'

        },
        ,
        {
          id: 52,
          content: '1223',
          content2: 'asdasd',

          date: '周一'

        }
      ],
      dataSource: []
    }
  },
  mounted () {
    this.dataSource = this.convertData(this.datas)
    console.log('   this.dataSource : ', this.dataSource);
  },
  methods: {
    dateRender (value, row, index) {
      return {
        children: value,
        attrs: {
          rowSpan: row.dateRowSpan
        },
      };
    },
    // 获取需要合并数据的rowSpan
    convertData (arr, levelIndex = 0) {
      const levelKey = this.sortLevel
      const key = levelKey[levelIndex]

      // 根据不同维度重新整合数据
      let groupObj = this.groupBy(arr, key) || {};
      Object.keys(groupObj).forEach(groupKey => {
        if (levelIndex < levelKey.length - 1) {
          groupObj[groupKey] = this.convertData(groupObj[groupKey], levelIndex + 1)
        }
        // 计算rowSpan
        groupObj[groupKey].forEach((item, index, arr) => {
          item[`${key}RowSpan`] = index === 0 ? arr.length : 0
        })
      })

      return Object.values(groupObj).flat()
    },
    // 根据属性分组
    groupBy (arr = [], key) {
      let obj = {}
      arr.forEach(item => {
        const val = item[key]
        if (!obj[val]) {
          obj[val] = []
        }
        obj[val].push(item)
      })

      return obj
    },
  },
}
</script>
<style lang="less" scoped></style>```
相关推荐
ywf12153 小时前
前端的dist包放到后端springboot项目下一起打包
前端·spring boot·后端
恋猫de小郭3 小时前
2026,Android Compose 终于支持 Hot Reload 了,但是收费
android·前端·flutter
hpoenixf9 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特10 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷10 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian11 小时前
前端node常用配置
前端
华洛11 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq11 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A12 小时前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常12 小时前
被EdgeToEdge适配折磨疯了,谁懂!
前端