element基于表头返回 merge: true 配置列合并

发布于:2025-05-16 ⋅ 阅读:(21) ⋅ 点赞:(0)
<template>
  <div class="wrap" v-loading="listLoading">
    <div class="content_wrap mt-10">
      <div style="text-align: center;">
        <h3>酿造交酒酒罐统计表({{month}}{{day}}日)</h3>
      </div>
      <div class="fr"><h4>单位:个</h4></div>
      <el-table 
        :data="dataList" 
        style="width: 100%" 
        border 
        :span-method="objectSpanMethod"
      >
        <!-- 遍历表头 -->
        <template v-for="(column, index) in tableHeader">
          <el-table-column
            v-if="column.children"
            :label="column.propName"
            align="center"
            width="150px"
          >
            <!-- 遍历二级表头 -->
            <el-table-column
              v-for="(childColumn, childIndex) in column.children"
              :key="childIndex"
              :label="childColumn.propName"
              :prop="childColumn.prop"
              width="150px"
              align="center"
            >
            </el-table-column>
          </el-table-column>
          <!-- 如果是一级表头(没有子表头) -->
          <el-table-column
            v-else
            :label="column.propName"
            :prop="column.prop"
            align="center"
            width="150px"
          ></el-table-column>
        </template>
      </el-table>
    </div>
  </div>
</template>

<script> 
import { mapGetters } from 'vuex'
import { Message } from 'element-ui'
import { stamnosstatistics } from "../../api/TasteandgradeApi";

export default {
  name: 'Winecanstatistics',
  data() {
    return {
      tableHeader: [],
      dataList: [], 
      tableColumnList: [],
      listLoading: false,
      month: '',
      day: '',
      spanMaps: {}, // 存储所有需要合并列的合并规则
      mergeColumns: [] // 存储所有需要合并的列prop
    }
  },
  mounted() {
    this.getdata()
    this.getTableData()
  },
  methods: {
    getdata() {
      const now = new Date();
      this.month = now.getMonth() + 1;
      this.day = now.getDate();
    },
    
    getTableData() {
      stamnosstatistics().then((response) => {
        this.dataList = response.data.result.dataList
        this.tableHeader = response.data.result.columnList
        // 提取需要合并的列
        this.extractMergeColumns()
        // 计算合并规则
        this.calculateSpans()
      })
    },
    
    // 递归提取所有标记了merge:true的列
    extractMergeColumns() {
      this.mergeColumns = []
      
      const findMergeColumns = (columns) => {
        columns.forEach(column => {
          if (column.merge) {
            this.mergeColumns.push(column.prop)
          }
          if (column.children) {
            findMergeColumns(column.children)
          }
        })
      }
      
      findMergeColumns(this.tableHeader)
    },
    
    // 计算所有需要合并列的合并规则
    calculateSpans() {
      this.spanMaps = {}
      
      this.mergeColumns.forEach(prop => {
        const spanMap = new Map()
        let pos = 0
        
        // 初始化,所有行默认不合并(rowspan=1)
        for (let i = 0; i < this.dataList.length; i++) {
          spanMap.set(i, 1)
        }
        
        // 计算合并规则
        for (let i = 1; i < this.dataList.length; i++) {
          // 当前行与上一行值相同则合并
          if (this.dataList[i][prop] === this.dataList[i - 1][prop]) {
            spanMap.set(pos, spanMap.get(pos) + 1) // 合并行数+1
            spanMap.set(i, 0) // 当前行设置为0表示被合并
          } else {
            pos = i // 值不同,重置合并位置
          }
        }
        
        this.spanMaps[prop] = spanMap
      })
    },
    
    // Element表格合并单元格方法
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 获取当前列的prop
      const currentProp = this.getColumnProp(columnIndex)
      
      // 如果当前列是需要合并的列
      if (currentProp && this.spanMaps[currentProp]) {
        const rowspan = this.spanMaps[currentProp].get(rowIndex)
        const colspan = rowspan > 0 ? 1 : 0
        
        return {
          rowspan,
          colspan
        }
      }
    },
    
    // 根据列索引获取列的prop
    getColumnProp(columnIndex) {
      let currentIndex = 0
      
      const findProp = (columns) => {
        for (const column of columns) {
          if (column.children) {
            const prop = findProp(column.children)
            if (prop) return prop
          } else {
            if (currentIndex === columnIndex) {
              return column.prop
            }
            currentIndex++
          }
        }
        return null
      }
      
      return findProp(this.tableHeader)
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
</style>
[
  {
    propName: '分类',
    prop: 'category',
    merge: true // 此列需要合并
  },
  {
    propName: '春天酒',
    children: [
      {
        propName: '货场空罐',
        prop: 'chuntianjiu_inEmpty',
        merge: true // 此列需要合并
      },
      {
        propName: '货场满罐',
        prop: 'chuntianjiu_inFull'
      }
    ]
  }
]

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到