React Antd 实现表格合计功能

思路:首先拿到 表格数组对象,然后写一个工具类,然后向数组对象最后插入一条数据,这条数据的字段时根据表格数组里合计算出来的。

代码如下,需根据各自业务稍作改动:

 <Table dataSource={tableData}
                   columns={columns}
                   pagination={false}
            />
    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)} />);
            },

    ]
}


    // 每次数据变更计算一次合计
    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);
    }, []);

合计工具类

/**
 * 用于表格的合计计算
 *
 * @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)); // 求和
        }
      }
    }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值