三级嵌套的json数据自动生成表格并合并单元格

【需求】

三级嵌套的json数据 :班级嵌套学生,学生中嵌套全部时间的考试成绩, 自动生成表格并合并单元格,如图
在这里插入图片描述

【原理】

将三级嵌套的数据扁平化成为一级,再根据主合并的字段,判断相同即记录合并的行数,

【json数据】

[{
      className: '高一三班',
      studentList:[
        {
        name: '张三',
        age: 18,
        achievement:[
          {
            time:'7年级-期中',
            yu:'80',
            shu:'90',
            ying:'100'
          },
          ...
        ]
      }
      ...
    ],
    jigelv:'80%',
    gaofenlv:'30%'
  }
  ...
]
    
        

【代码】

<template>
  <div style="padding: 20px;">
    <el-table :data="buildData" 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-column label="班级" align="center" prop="className" />
      <el-table-column label="姓名" align="center" prop="name" />
      <el-table-column label="年龄" align="center" prop="age" /> -->
    </el-table>
  </div>
</template>

<script>
  const datas = [{
      className: '高一三班',
      studentList:[
        {
        name: '张三',
        age: 18,
        achievement:[
          {
            time:'7年级-期中',
            yu:'80',
            shu:'90',
            ying:'100'
          },
          {
            time:'7年级-期末',
            yu:'82',
            shu:'91',
            ying:'103'
          },
        ]
       },
        {
          name: '李四',
          age: 19,
          achievement:[
            {
              time:'7年级-期中',
              yu:'80',
              shu:'90',
              ying:'100'
            },
            {
              time:'7年级-期末',
              yu:'82',
              shu:'91',
              ying:'103'
            },
          ]
        },
      ],
      jigelv:'80%',
      gaofenlv:'30%'
    },
    {
      className: '高一五班',
      studentList:[
        {
        name: '张其',
        age: 18,
        achievement:[
          {
            time:'7年级-期中',
            yu:'80',
            shu:'90',
            ying:'100'
          },
          {
            time:'7年级-期末',
            yu:'82',
            shu:'91',
            ying:'103'
          },
        ]
       },
        {
          name: '王芳',
          age: 19,
          achievement:[
            {
              time:'7年级-期中',
              yu:'80',
              shu:'90',
              ying:'100'
            },
            {
              time:'7年级-期末',
              yu:'82',
              shu:'91',
              ying:'103'
            },
          ]
        },
      ],
      jigelv:'70%',
      gaofenlv:'20%'
    },
    {
      className: '高一六班',
      studentList:[
        {
        name: '张其',
        age: 18,
        achievement:[
          {
            time:'7年级-期中',
            yu:'80',
            shu:'90',
            ying:'100'
          },
          {
            time:'7年级-期末',
            yu:'82',
            shu:'91',
            ying:'103'
          },
        ]
       },
        {
          name: '王芳',
          age: 19,
          achievement:[
            {
              time:'7年级-期中',
              yu:'80',
              shu:'90',
              ying:'100'
            },
            {
              time:'7年级-期末',
              yu:'82',
              shu:'91',
              ying:'103'
            },
            {
              time:'8年级-期中',
              yu:'80',
              shu:'90',
              ying:'100'
            },
            {
              time:'8年级-期末',
              yu:'82',
              shu:'91',
              ying:'103'
            },
          ]
        },
      ],
      jigelv:'50%',
      gaofenlv:'10%'
    },
  ]
  export default {
    name: "MultiRowMergeTable",
    data() {
      this.spanMap = {};
      this.mergedColumns = ["className","name","age"]
      this.mergedMainColumns = ["jigelv","gaofenlv"]
      return {
        tableHeader: [{
            prop: "className",
            label: "班级",
          },
          {
            prop: "name",
            label: "姓名",
          },
          {
            prop: "age",
            label: "年龄",
          },
          {
            prop: "time",
            label: "考试时间",
          },
          {
            prop: "yu",
            label: "语文",
          },
          {
            prop: "shu",
            label: "数学",
          },
          {
            prop: "ying",
            label: "英语",
          },
          {
            prop: "jigelv",
            label: "及格率"
          },
          {
            prop: "gaofenlv",
            label: "高分率"
          },
        ],
        tableData: [],
      }
    },
    created() {
      this.getList(); //进入页面时调用getList()获取tableData[]数据
    },
    computed:{
      buildData(){
        let data=this.tableData
        if(!data) return
        let datas = this.flattenArray(data)
        console.log(datas)
        this.getSpanArr(datas, this.mergedColumns)
        return datas
      }
    },
    methods: {
      //具体获取数据方法因需求而异
      getList() {
        // listExamineTableData(this.queryParams).then(response => {
        //   this.tableData = response.data;
        //   this.getSpanArr(this.tableData);
        // });
        this.tableData = datas;
        // console.log(this.tableData)
      },
      flattenArray(arr) {
        let result=[]
        let id=''
        arr.forEach((obj,xh)=>{
          let one=xh.toString()
          const { studentList: child, ...otherProps } = obj;
          if(child && child.length>0){
            child.forEach((item,index)=>{
              let two=index.toString()
              const {achievement: childTwo, ...otherItem} = item
              if(childTwo && childTwo.length>0){
                childTwo.forEach((third,thirdIndex)=>{
                  let three=thirdIndex.toString()
                  id=one+'-'+two+'-'+three
                  result.push({id, ...otherProps, ...third, ...otherItem});
                })
              }else{
                id=one+'-'+two
                result.push({id, ...otherProps, ...otherItem});
              }
            })
          }else{
            id=one
            result.push({id,...otherProps})
          }
        })
        // console.log(result)
        return result;
      },
      getSpanArr(data) {
        for (var i = 0; i < data.length; i++) {
          if (i === 0) {
            this.mergedColumns.forEach(column => {
              this.spanMap[column] = {
                spanArr: [1],
                pos: 0,
                // index:i
              }
            })
          } 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;
              }
              // this.spanMap[column].index=i
            })
          }
          // console.log(this.spanMap)
        }
        this.mergedMainColumns.forEach(column => {
          this.spanMap[column] = this.spanMap["className"]
        })
      },
      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>
<style>
</style>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值