antd中如何给Table表格添加合计行

最近项目需求:在表格底部添加一行为金额的合计行,然后分页每页都显示,金额字段是后端返回的数据,前端不进行计算。

因为项目的UI框架使用的是Ant Design 3.x版本,找了一下Table的使用方法,发现居然没有合计数据这样一个功能,但是提供了一个footer属性用来做Table底部的空间显示。然后我使用footer中添加一个Table来做了一下合计行显示,勉强能做出来,但是需要修改Table的css样式,并且在不同分辨率下表格的线框无法对齐,总之就是很low。

多方查找资料,以及自己的不断试错,终于找到了一种颇为完美的解决方法:将合计行追加到table表格内部,修改分页功能,维护也更加方便。

先上图,切换分页后table底部也有合计行:

上代码:

import React, { PureComponent } from 'react';
import { Table } from 'antd';
import { formatMoney } from '@/utils/utils'; //自定义格式化金额方法

//  columns中的多余字段删除掉了,都是重复的样式,这里为了减少代码量。
const columns = [
  {
    title: '序号',
    width: 66,
    dataIndex: 'totalIndex',
    render: (text, record, index) => {
      if (record.totalIndex == '合计') {
        return text;
      } else {
        return ++index;  //++index相当于index+1
      }
    }
  },
  {
    title: '凭证号',
    width: 200,
    dataIndex: 'voucherCode',
    render: (text, record) => {
      //因为只有合计行追加了字段totalIndex,所以判断当前字段来让合计行的凭证号列数据为空,只计算金额列。
      //产品说让空白显示!!!
      if (record.totalIndex) {  
        return '';
      } else {
        return text || '--';
      }
    }
  },
  {
    title: '借方金额',
    dataIndex: 'debit',
    render: text => formatMoney(text)
  },
  {
    title: '贷方金额',
    dataIndex: 'credit',
    render: text => formatMoney(text)
  }
];

export default class ListTable extends PureComponent {
  // 切换分页时调用函数
  changePagination = pagination => {
    const {
      dispatch,
      queryFinanceList: { formValues }
    } = this.props;
    const params = {
      page: pagination.current,        //当前分页的页码
      limit: pagination.pageSize - 1,  //这里必须要减1,因为与后台规定每页获取的数据为10,此处的pageSize为11。
      queryCondition: { ...formValues },
    };
    dispatch({
      type: 'queryFinanceList/fetch',
      payload: params,
    });
  };

  render() {
    const {
      loading,
      queryFinanceList: {
        list,
        pageNum,
        total: computedTotal,  //重命名为computedTotal
        pages,
        pageSize
      },
    } = this.props;
    //定义合计行数据
    const totalRow = {
      id: String(Math.random()),
      totalIndex: '合计',
      debit: 1165000,  //应当取从后台返回数据,此处为演示,所以自定义了默认值
      credit: 1183000, //应当取从后台返回数据,此处为演示,所以自定义了默认值
    }
    //将合计行数据添加到list数组中后生成新数组:_list,此时table每页的数据为11
    const _list = list && list.length > 0 ? [...list, totalRow] : [];
    //table与pagination组件之间的联动
    //因为table表格每页显示的数据被pagenation分页默认的每页显示数pageSize所限制,默认为10,为了让合计行显示到页面上,需+1。
    const _pageSize = pageSize + 1;
    //table表格需要获取的总数据,为了让table将后台获取数据和新增合计行数据全部显示出来,需重新计算总数。
    const _total = computedTotal + pages;
    //分页设置
	const paginationDefault = {
      showSizeChanger: true,
      showQuickJumper: true,
      current: pageNum,
      total: _total,
      pageSize: _pageSize,
      //因为与后台规定每页获取的数据为10,而前端自定义追加了一条合计行,这导致当前table的每页数据为11条,所以需要手动将分页数据+1
      //若是想显示为['10', '20', '30', '40'],则修改每页获取数据为9即可。
      pageSizeOptions: ['11', '21', '31', '41'], 
      //此处显示的是从后台获取的总数据数,合计行不在其中。
      showTotal: () => `${computedTotal}条记录`
    }
    
    return (
      <Table
        loading={loading}
        rowKey={'id'}
        scroll={{ x: true }}
        bordered={true}
        loading={loading}
        columns={columns}
        dataSource={_list}
        pagination={paginationDefault}  
        onChange={this.changePagination}
      />
    );
  }
}

如果使用过ant design的Table组件以及Pagination组件的话,上面基本没有什么难点。
逻辑理解的话有两个难点:
1、分页功能的total和pageSize的计算方式?
2、合计行totalRow与后台返回数据的关系?

在table表格中使用pagination分页功能后,table每页显示的数据被pagination的pageSize(每页显示数据)限制,如果pageSize为10的话,那table中每页就只能显示10条数据。现在我们手动给table添加了合计行totalRow,那table每页的数据显示就变为了11,这时候pageSize若还是10,那第11条数据是显示不出来的,所以pageSize需要修改为11,这样合计行totalRow就能显示出来了。我们在切换分页的时候,是需要请求后台数据的,pageSize需要当做请求参数传送给后台。但是这时候我们设定了pageSize为11,而规定的每页显示的真实数据为10,所以需要在请求数据时pageSize-1。

total也需要跟随pageSize的+1而改变。如果后台返回的total为61,pageSize为10,pages(几个页面)为7,那么“新total”的计算方式为:61+1*7=68。因为在table每页中都添加了一条合计行totalRow的数据,所以计算方式为61+1*7=68。如果手动添加了两条数据,那么总数计算就应当为:61+2*7=75。

若还有更优美的实现方式,欢迎留言分享。

参考:react:antd 中 table 添加合计行

你可能感兴趣的:(#,React,table,pagination,合计行,summary)