vxe-table行列计算
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>