思路:首先拿到 表格数组对象,然后写一个工具类,然后向数组对象最后插入一条数据,这条数据的字段时根据表格数组里合计算出来的。
代码如下,需根据各自业务稍作改动:
html
<Table dataSource={tableData}
columns={columns}
pagination={false}
/>
javascript
const columns = [
{
title: 'xxx',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: 'yyy',
dataIndex: 'yyy',
key: '',
align: 'center',
render: (text, record, rowIndex) => {
return (<InputNumber min={0} value={text}
onChange={(e) => handleCellChange(rowIndex, 'yyy', e)} />);
},
]
}
javascript
// 每次数据变更计算一次合计
const handleCellChange = (rowIndex, dataIndex, value) => {
const newTableData = _.cloneDeep(tableData);
newTableData[rowIndex][dataIndex] = value;
countSum(newTableData, '', 'project');
setTableData(newTableData);
};
// 第一次进来计算一次合计
React.useEffect(() => {
const newTableData = _.cloneDeep(tableData);
countSum(newTableData, '', 'project');
setTableData(newTableData);
}, []);
合计工具类
javascript
/**
* 用于表格的合计计算
*
* @param arr 要计算的数组
* @param prefix 要计算的数组的对象的前缀
* @param sumField 合计字段名字放到哪个字段上
* @param accuracy 合计精度
* @returns {*}
*/
export function countSum(arr, prefix, sumField, accuracy = 4) {
if (arr.length === 0) {
// 没数据,直接返回
return;
}
// 求和对象
let sumObj = {};
// 获取到最后一个数据
let last = arr[arr.length - 1];
if (prefix) {
if (last[prefix][sumField] === '合计') {
// 已经存在合计了
sumObj = last;
// 把 sum 的值清空,重新计算
sumObj[prefix] = {};
sumObj[prefix][sumField] = '合计';
} else {
sumObj[prefix] = {};
sumObj[prefix][sumField] = '合计';
arr.push(sumObj); // 在数组末尾添加合计对象
}
} else {
if (last[sumField] === '合计') {
// 已经存在合计了
last = {};
last[sumField] = '合计';
arr[arr.length - 1] = last;
sumObj = last;
} else {
sumObj[sumField] = '合计';
arr.push(sumObj); // 在数组末尾添加合计对象
}
}
let attrNames;
if (prefix) {
attrNames = Object.keys(arr[0][prefix]); // 获取数组中所有对象的属性名
} else {
attrNames = Object.keys(arr[0]); // 获取数组中所有对象的属性名
}
// -1 代表不累计合计本身的值
for (let i = 0; i < attrNames.length - 1; i++) {
const attrName = attrNames[i];
for (let j = 0; j < arr.length - 1; j++) {
let attrValue;
if (prefix) {
attrValue = arr[j][prefix][attrName];
} else {
attrValue = arr[j][attrName];
}
if (typeof attrValue == 'number') {
// 只合计数值类型
// 将属性值转换为数值类型
let attrValueNumber = Number(attrValue).toFixed(4);
if (prefix) {
sumObj[prefix][attrName] = Number(parseFloat(Number(sumObj[prefix][attrName] || 0) + Number(attrValueNumber)).toFixed(accuracy)); // 求和
} else {
sumObj[attrName] = Number(parseFloat(Number(sumObj[attrName] || 0) + Number(attrValueNumber)).toFixed(accuracy)); // 求和
}
}
}
}
}