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)); // 求和
        }
      }
    }
  }
}
相关推荐
美狐美颜sdk1 小时前
跨平台直播美颜sdk集成攻略:Android、iOS与Web的统一方案
android·前端·ios
Airser1 小时前
npm启动Taro框架报错
前端·npm·taro
Anlici2 小时前
连载小说大学生课设 需求&架构
前端·javascript·后端
2501_938769993 小时前
React Server Components 进阶:数据预取与缓存
前端·react.js·缓存
蒜香拿铁3 小时前
Angular【基础语法】
前端·javascript·angular.js
xiaoxiao无脸男4 小时前
纯css:一个好玩的按钮边框动态动画
前端·css·css3
rookie_fly4 小时前
基于Vue的数字输入框指令
前端·vue.js·设计模式
元直数字电路验证4 小时前
ASP.NET Core Web APP(MVC)开发中无法全局配置 NuGet 包,该怎么解?
前端·javascript·ui·docker·asp.net·.net
rexling15 小时前
【Spring Boot】Spring Boot解决循环依赖
java·前端·spring boot
我有一棵树5 小时前
Vue 项目中全局样式的正确写法:不要把字体和主题写在 #app 上
前端·javascript·vue.js