React Antd 实现表格合计功能

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

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

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)); // 求和
        }
      }
    }
  }
}
相关推荐
兮动人1 分钟前
Google Chrome 142更新引发内网访问危机:原理、影响与全面解决方案
前端·chrome
PAQQ2 分钟前
ubuntu22.04 搭建 Opencv & C++ 环境
前端·webpack·node.js
这是个栗子8 分钟前
git报错:Reinitialized existing Git repository in ...
前端·git·github
ghfdgbg10 分钟前
15. Vue工程化 + ElementPlus
前端·javascript·vue.js
Onlyᝰ12 分钟前
前端使用jscpd查项目重复率
前端
pandarking21 分钟前
[CTF]攻防世界:web-unfinish(sql二次注入)
前端·数据库·sql·web安全·ctf
IT_陈寒21 分钟前
Java并发编程避坑指南:从volatile到ThreadLocal,8个实战案例解析线程安全核心原理
前端·人工智能·后端
Light6025 分钟前
Signal 与现代前端框架的响应式机制
性能优化·前端框架·边缘计算·signal·细粒度响应·ai驱动界面
ByteCraze26 分钟前
前端性能与监控指标采集系统设计方案
前端
山楂树の32 分钟前
前端实时渲染性能优化 使用cocoRLE编码进行图像传输并着色绘制
前端·图像处理·实时互动