vxe-table行列计算

(此篇为转载,记录备忘)

实现功能

根据树状结构数据,在vxe-table可编辑表格表格中实现如下功能:

每一行的第一列数据等于当前行数据的和;
父类的每一列数据等于子类每一项相加;
自定义计算的单元格禁用,其余单元格可编辑数据。

实现效果图

在这里插入图片描述

完整代码

<template>
  <!-- activeCellMethod: 判断单元格是否禁用 -->
  <vxe-table border
             resizable
             highlight-current-row
             :max-height="height"
             :data="listData"
             style="width: 100%"
             :tree-config="tableTreeConfig"
             :edit-config="{trigger: 'click', mode: 'cell', activeMethod: activeCellMethod}"
             :keyboard-config="{isArrow: true}">
    <vxe-table-column align="center"
                      field="project"
                      min-width="120"
                      title="项目"
                      tree-node
                      :formatter="formatName"
                      :edit-render="{name: 'input'}" />
    <vxe-table-column align="center"
                      field="amount"
                      min-width="100"
                      title="资金合计">
      <template v-slot="{ row }">
        <span>{{ countAmount(row) }}</span>
      </template>
    </vxe-table-column>
    <vxe-table-column align="center"
                      field="currency"
                      min-width="100"
                      title="货币"
                      :edit-render="{name: '$input', props: {type: 'float', digits: 2}}" />
    <vxe-table-column align="center"
                      field="silver"
                      min-width="100"
                      title="网银"
                      :edit-render="{name: '$input', props: {type: 'float', digits: 2}}" />
    <vxe-table-column align="center"
                      field="shang"
                      min-width="100"
                      title="商品"
                      :edit-render="{name: '$input', props: {type: 'float', digits: 2}}" />
    <vxe-table-column align="center"
                      field="remark"
                      min-width="100"
                      title="备注"
                      :edit-render="{name: '$input'}" />
  </vxe-table>
</template>

<script>
// 导入xe-utils函数库
import XEUtils from 'xe-utils'
export default {
  name: 'demo',
  data() {
    return {
      tableTreeConfig: {
        children: 'children',
        accordion: false, // 一层只允许展开一个节点
        expandAll: false // 默认是否全部展开
      },
      height: 700,//表格高度
      unusableAmount: [],
      listData: []
    }
  },
  created() {
    setTimeout(() => {
      const temp = [
        {
          id: 0,
          pid: null,
          project: '本金',
          amount: 1000,
          currency: 500,
          silver: 200,
          shang: 300,
          remark: ''
        }, {
          id: 1,
          pid: null,
          project: '收款',
          amount: null,
          currency: null,
          silver: null,
          shang: null,
          remark: '',
          children: [
            {
              id: 1,
              pid: 1,
              project: '收款项1',
              amount: null,
              currency: null,
              silver: null,
              shang: null,
              remark: '',
            }, {
              id: 2,
              pid: 1,
              project: '收款项2',
              amount: null,
              currency: null,
              silver: null,
              shang: null,
              remark: '',
            }, {
              id: 3,
              pid: 1,
              project: '收款项3',
              amount: null,
              currency: null,
              silver: null,
              shang: null,
              remark: '',
            }
          ]
        }, {
          id: 2,
          pid: null,
          project: '付款',
          amount: null,
          currency: null,
          silver: null,
          shang: null,
          remark: '',
          children: [
            {
              id: 1,
              pid: 2,
              project: '付款项1',
              amount: null,
              currency: null,
              silver: null,
              shang: null,
              remark: '',
            }, {
              id: 2,
              pid: 2,
              project: '付款项2',
              amount: null,
              currency: null,
              silver: null,
              shang: null,
              remark: '',
            }, {
              id: 3,
              pid: 2,
              project: '付款项3',
              amount: null,
              currency: null,
              silver: null,
              shang: null,
              remark: '',
            }
          ]
        }, {
          id: 3,
          pid: null,
          project: '总值',
          amount: null,
          currency: null,
          silver: null,
          shang: null,
          remark: '',
        }
      ]
      this.listData = this.getGroupSummary(temp)
    }, 1000)
  },
  methods: {
    // 计算公式
    // 总值 = 本金 + 收款 - 付款
    calculateAmount(sum1, sum2, minuend) {
      return XEUtils.subtract(XEUtils.add(sum1, sum2), minuend)
    },
    // 合计当前行数据
    countAmount(row) {
      switch (row.project) {
        case '总值':
          row.amount = this.calculateAmount(this.listData[0].amount, this.listData[1].amount, this.listData[2].amount)
          break;
        default:
          row.amount = XEUtils.add(XEUtils.add(row.currency, row.silver), row.shang)
          break;
      }
      return row.amount
    },
    formatName({ row }) {
      return row.children && row.children.length ? `${row.project} (${row.children.length}项)` : row.project
    },
    // 计算逻辑
    handleSummary(children) {
      return {
        currency: Math.floor(XEUtils.sum(children, 'currency')),
        silver: Math.floor(XEUtils.sum(children, 'silver')),
        shang: Math.floor(XEUtils.sum(children, 'shang'))
      }
    },
    getGroupSummary(data) {
      XEUtils.eachTree(data, (row, index, items, path, parent, nodes) => {
        let children = row.children
        if (children && children.length) {
          // 合计子节点
          Object.assign(row, this.handleSummary(children))
        } else {
          if (index === items.length - 1) {
            // 全量汇总
            for (let len = nodes.length - 2; len >= 0; len--) {
              Object.assign(nodes[len], this.handleSummary(nodes[len].children))
            }
          }
        }
      }, this.tableTreeConfig)
      data[3].currency = this.calculateAmount(data[0].currency, data[1].currency, data[2].currency)
      data[3].silver = this.calculateAmount(data[0].silver, data[1].silver, data[2].silver)
      data[3].shang = this.calculateAmount(data[0].shang, data[1].shang, data[2].shang)
      return data
    },
    // 判断单元格是否禁用
    activeCellMethod({ column, columnIndex, row }) {
      console.log(column, 'column')
      if (columnIndex === 1 || columnIndex === 0 || row.project === '本金' || row.project === '收款' || row.project === '付款' || row.project === '总值') {
        return false
      }
      this.listData = this.getGroupSummary(this.listData)
      return true
    },
  }
}
</script>

<style lang="scss" >
.vxe-table.is--empty .vxe-table--empty-placeholder {
  height: 400px !important;
}
</style>



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值