el-table 表尾行合并,列合并,统计

后端返回的数据中有统计好的信息

效果

el-table 表尾行合并,列合并,统计_第1张图片

代码

<template>
  <div class="result-record">
    <div v-for="(table, tableIndex) in tableData" :key="tableIndex" :class="tableIndex !== 0 ? 'mrt20' : ''">
      <!-- show-summary :summary-method="getSummaries" -->
      <el-table :data="table" border stripe :span-method="objectSpanMethod" style="width: 100%;">
        <el-table-column
          v-for="(item, index) in columns"
          :key="index"
          show-overflow-tooltip
          :prop="item.key"
          :label="item.columnName"
          :width="item.width"
        />
      </el-table>
    </div>
  </div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
  name: 'ResultRecord',
  props: {
  },
  emits: {
  },
  setup () {
    const columns = ref([
      {
        key: 'time',
        columnName: '操作时间(月)',
        width: ''
      },
      {
        key: 'opsType',
        columnName: '操作类型',
        width: ''
      },
      {
        key: 'cnt',
        columnName: '记录数量',
        width: ''
      }
    ])
    const tableData = ref(
      [
        [
          {
            time: '2021/08',
            opsType: 'SELECT',
            cnt: 6
          },
          {
            time: '2021/08',
            opsType: 'DROP',
            cnt: 3
          },
          {
            time: '2021/08',
            opsType: 'CREATE',
            cnt: 4
          },
          {
            time: '2021/08',
            opsType: 'INSERT',
            cnt: 7
          },
          {
            time: '行汇总(总计)',
            opsType: '',
            cnt: 20
          }
        ],
        // [
        //   {
        //     time: '2021/08',
        //     opsType: 'SELECT',
        //     cnt: 1
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'DROP',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'CREATE',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'INSERT',
        //     cnt: 1
        //   }
        // ],
        // [
        //   {
        //     time: '2021/08',
        //     opsType: 'SELECT',
        //     cnt: 1
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'DROP',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'CREATE',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'INSERT',
        //     cnt: 1
        //   }
        // ]
      ]
    )
    const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
      if (rowIndex === 4) {
        // 处理合计,[1,2]表示合并1行2列,[0,0]表示改行不显示
        if (columnIndex === 0) {
          // 定位到4行0列的ID,告诉该单元格合并1行2列
          return [1, 2]
        } else if (columnIndex === 1) {
          // 定位到6行1列的姓名,告诉该单元格不显示
          return [0, 0]
        }
      } else {
        if (columnIndex === 0) {
          if (rowIndex % 4 === 0) {
            return {
              rowspan: 4,
              colspan: 1
            }
          } else {
            return {
              rowspan: 0,
              colspan: 0
            }
          }
        }
      }
    }
    const getSummaries = (param) => {
      const { columns, data } = param
      const sums = []
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '行汇总(总计)'
          // 只计算最后一列
        } else if (index === columns.length - 1) {
          const values = data.map(item => Number(item[column.property]))
          if (!values.every(value => isNaN(value))) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr)
              if (!isNaN(value)) {
                return prev + curr
              } else {
                return prev
              }
            }, 0)
          } else {
            sums[index] = ''
          }
        } else {
          sums[index] = ''
        }
      })
      return sums
    }
    return {
      columns,
      tableData,
      getSummaries,
      objectSpanMethod
    }
  }
})
</script>
<style lang="scss" scoped>
@import '@/styles/common-style.scss';

.result-record {
}

</style>

后端没有给统计好的数据需要前端自己定义最后一列

效果

el-table 表尾行合并,列合并,统计_第2张图片

<template>
  <div class="result-record">
    <div v-for="(table, tableIndex) in tableData" :key="tableIndex" :class="tableIndex !== 0 ? 'mrt20' : ''">
      <el-table :data="table" border stripe :span-method="objectSpanMethod" show-summary :summary-method="getSummaries" style="width: 100%;">
        <el-table-column
          v-for="(item, index) in columns"
          :key="index"
          show-overflow-tooltip
          :prop="item.key"
          :label="item.columnName"
          :width="item.width"
        />
      </el-table>
    </div>
  </div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
  name: 'ResultRecord',
  props: {
  },
  emits: {
  },
  setup () {
    const columns = ref([
      {
        key: 'time',
        columnName: '操作时间(月)',
        width: ''
      },
      {
        key: 'opsType',
        columnName: '操作类型',
        width: ''
      },
      {
        key: 'cnt',
        columnName: '记录数量',
        width: ''
      }
    ])
    const tableData = ref(
      [
        [
          {
            time: '2021/08',
            opsType: 'SELECT',
            cnt: 6
          },
          {
            time: '2021/08',
            opsType: 'DROP',
            cnt: 3
          },
          {
            time: '2021/08',
            opsType: 'CREATE',
            cnt: 4
          },
          {
            time: '2021/08',
            opsType: 'INSERT',
            cnt: 7
          },
          // {
          //   time: '行汇总(总计)',
          //   opsType: '',
          //   cnt: 20
          // }
        ],
        // [
        //   {
        //     time: '2021/08',
        //     opsType: 'SELECT',
        //     cnt: 1
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'DROP',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'CREATE',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'INSERT',
        //     cnt: 1
        //   }
        // ],
        // [
        //   {
        //     time: '2021/08',
        //     opsType: 'SELECT',
        //     cnt: 1
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'DROP',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'CREATE',
        //     cnt: 3
        //   },
        //   {
        //     time: '2021/08',
        //     opsType: 'INSERT',
        //     cnt: 1
        //   }
        // ]
      ]
    )
    const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
      if (rowIndex === 4) {
        // 处理合计,[1,2]表示合并1行2列,[0,0]表示改行不显示
        if (columnIndex === 0) {
          // 定位到4行0列的ID,告诉该单元格合并1行2列
          return [1, 2]
        } else if (columnIndex === 1) {
          // 定位到6行1列的姓名,告诉该单元格不显示
          return [0, 0]
        }
      } else {
        if (columnIndex === 0) {
          if (rowIndex % 4 === 0) {
            return {
              rowspan: 4,
              colspan: 1
            }
          } else {
            return {
              rowspan: 0,
              colspan: 0
            }
          }
        }
      }
    }
    const getSummaries = (param) => {
      const { columns, data } = param
      const sums = []
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '行汇总(总计)'
          // 只计算最后一列
        } else if (index === columns.length - 1) {
          const values = data.map(item => Number(item[column.property]))
          if (!values.every(value => isNaN(value))) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr)
              if (!isNaN(value)) {
                return prev + curr
              } else {
                return prev
              }
            }, 0)
          } else {
            sums[index] = ''
          }
        } else {
          sums[index] = ''
        }
      })
      return sums
    }
    return {
      columns,
      tableData,
      getSummaries,
      objectSpanMethod
    }
  }
})
</script>
<style lang="scss" scoped>
@import '@/styles/common-style.scss';

.result-record {
}

</style>

你可能感兴趣的:(前端,vue.js,javascript,前端)