Ant-design: 无法在表中显示聚合统计数据

创建于 2017-04-11  ·  78评论  ·  资料来源: ant-design/ant-design

2.9.1

环境

浏览器

复制链接

http://无

重现步骤

我想在表页脚显示聚合统计信息,我尝试以下方法:

  1. 使用footer道具,在其中添加trtd
      <Table
        dataSource={dataSource}
        footer={() => {
          return (
            <tr className='ant-table-row  ant-table-row-level-0'>
              <td>总计</td>
              <td>总计</td>
            <td>总计</td>
            </tr>
          )
        }}
      />
  1. dataSource prop中添加额外的数据
dataSource.push({id: '总计', price: '3000'})

期望什么?

一张图片胜过千言万语:

实际发生了什么?

  1. 使用footer道具,但是footer道具不适合桌子。

  2. dataSource道具中添加额外的数据,但是如果dataSource长度超过pageSize ,则多余的数据将被忽略。

Inactive IssueHuntFest ❓FAQ 💡 Feature Request

最有用的评论

也许我们可以做一些事情来使footer适合桌子的身体?

所有78条评论

您好@TangMonk ,似乎您要求的功能不是报告错误,恐怕我们没有实现此功能的计划。 您可以禁用表的默认分页并自行实现分页。

也许我们可以做一些事情来使footer适合桌子的身体?

@yesmeck ,谢谢您的答复,但是对此有太多问题,我认为此功能确实有用且必要。

相关问题:#3591,#1483,#4581

@ afc163 ,谢谢!

您有什么建议或解决方案?

我不确定,我认为不能通过使用pageSize来严格限制表数据大小,数据应该由服务器端而不是客户端处理,因此我们可以向表中添加任何额外的数据

你好
此功能是否有任何更新? 还是另一种方式呢?

@yesmeck最简单的解决方案是使页脚在表格渲染实际的<tfoot> ,而不是在表格外附加额外的<div>

人们试图将额外的行挤入dataSource仅仅是因为他们希望表布局为他们对齐列。

是的,我们已经有一个footer道具,无法为<tfoot/>确定一个合适的名称。

我建议重新实现当前的footer道具,使其呈现一个<tfoot />内部表,而不添加新的tfoot道具。 不要以为它会破坏任何东西。

@yesmeck似乎经常需要此功能。 我也在努力添加摘要行。 变通了,但涉及到恶意的dom操作,很高兴看到更漂亮的解决方案。

团队中有人在照顾它了吗? 如果没有,我可以调查一下。

您可以尝试PR。

@yesmeck到这里: https :
有关效果,请参见example / renderFooterInTable

考虑了一段时间tfoot API之后,我想将其添加到column属性中:

const columns = [{
  title: 'Age',
  dataIndex: 'age',
  key: 'age',
  footer: (data) => {
    return <div>Summary: {data.reduce((sum, record) => sum + record.age, 0)}</div>
  },
}, {
  title: 'Name',
  dataIndex: 'name',
  key: 'name',
}, {
  title: 'Address',
  dataIndex: 'address',
  key: 'address',
}];

渲染

screen shot 2018-02-27 at 15 03 33

更清楚地使当前Table[footer]之间有所不同。

好主意。 我同意这是挤入新API的更好的地方。

@hackape您可以提出新的PR吗?

确定的事情

https://codesandbox.io/s/m45r6o4nj8
实现了,但是滚动条联动出现了问题,更方便看下嘛

@yesmeck现在react-component / table#195的状态如何,有任何反馈吗?

看到它合并了👍 @yesmeck

但是,我收到了其他功能请求。 我想建议允许所谓的“页脚”出现在表格顶部,表格标题的正下方。

例:
image

一直在讨论的实际请求的功能是挤压显示统计信息的额外行(即“摘要行”)而不篡改dataSource的内容而不是“页脚”的意思。位置感。

@hackape您可以使用列分组,请参阅https://codesandbox.io/s/pmorq2x2lq

是的,仅仅是为了定位的目的,这将是一个可行的方法。 但是从业务逻辑的角度来看,最好是让用户通过我提出的API来做到这一点。

认为我们可以将column.footer API重命名为column.summary

const columns = [{
  title: 'Age',
  dataIndex: 'age',
  key: 'age',
  summary: {
    render: (data) => {
      return <div>Summary: {data.reduce((sum, record) => sum + record.age, 0)}</div>
    },
    position: 'bottom',  // default to 'bottom', could be 'top'
  }
}]

我建议介绍两个名为pinnedTopDatapinnedBottomData新职业玩家。

const columns = [
  { title: 'Price', dataIndex: 'price' },
  { name: 'Name', dataIndex: 'name' },
];

const data = [
  { price: 3, Name: 'Foo' },
  { price: 5, Name: 'Bar' },
];

const pinnedData = [
  { price: <span style={{ fontWeight: 'bold' }}>Total: 8</span> }
];

<Table
  columns={columns}
  dataSource={data}
  pinnedTopData={pinnedData}
  pinnedBottomData={pinnedData}
/>

渲染:

| 价格姓名|
| ---------- || ------ |
| 合计:8 | |
| 3 | 富|
| 5 | 酒吧
| 合计:8 | |

最好使用相同的API解决#6896和此问题。

有新进展吗?

@Nokecy 看他的解决方式有两种,他暂时没加到属性上,我看他的re-table有这个属性,前提是版本号升到最新,不过应该需要修改antd的package.json. 还有两种方法,
1.如果列不是很多,不出现滚动条的话,很好解决,我上面有个例子。
2.可以使用多个标题栏进行显示,感觉不是那么美观。

很期待他们把这个功能完善,一直在持续关注,不过我们的antd是2.,就算更新了,不知道2.版本会不会有这个属性

这个问题有更新吗??

在他们正式发布API之前,我建议提供一个table.props.components.body.wrapper自定义组件,并篡改它收到的props.children

https://codesandbox.io/s/xpvwpx0npw
我直接操作了dom元素,封装了一个合计总计的,可以按照这个方法加很多footer,但是官方不推荐直接操作dom元素,如果急用,这个可以参考下

@ LDD123在您的示例中,滚动x仅位于页

image

@jagratiTomar当页脚滚动时,主体将滚动,我将主体的scroll-x与页脚的scroll-x绑定在一起

您可以分享@ LDD123并举例说明正文中还存在滚动y的情况,因为在这种情况下,只有正文应滚动而不是页脚

@jagratiTomar现在,我隐藏的滚动-x不滚动,就可以了

@ LDD123,所以您说的是当滚动y时,此示例是否有效?

是的

你好@yesmeck @ afc163

我们的设计师出于UX目的,将页脚(具有汇总值)放在正文顶部,并在页眉下方。 页眉和页脚上的排序箭头仅具有汇总值。 使用ColumnGroup进行排序的箭头将附加到底部。 从样式的角度来看,对页脚进行样式设置并将其设置在顶部要容易得多,因为页脚容器具有不同的颜色,并且只有一些单元格具有分隔符。

我会做:

.my-table tfoot > tr {
 background-color: gray;
}

表组件可能具有以下内容:

<Table appendColumnFooterTop={true}>
   <Column
      footer={(data) => <div>Summary: {data.reduce((sum, record) => sum + record.age, 0)}</div>}
   />
</Table>

设计:
screen shot 2018-05-30 at 17 07 38

不要介意单元格中以前未完成的页面中未对齐的文本,它们必须与我们正在编码的新页面对齐。

如果我知道它可以在2或3周内发布(列脚及其对齐方式),我可以提供帮助。 否则,我将不得不寻找其他解决方案。

哦,我不明白#6896是否与列脚有关,所以我在这里写了。

谢谢。

@kaanozcan我在三此处),核心团队将其合并,然后将其还原。 似乎他们对如何解决该问题还有其他想法。 在这种情况下,我建议您采取“查找其他解决方案”的方法。

@kaanozcan这是一个通过自定义组件实现目标的示例https://codesandbox.io/s/xjpkx9rzzw

@yesmeck完美地工作。 谢谢。

由于原始请求而导致的关闭可以通过自定义组件来实现。

@yesmeck我们可以提供有关此使用案例的一些演示吗?

https://codesandbox.io/s/xjpkx9rzzw
这个例子并没有什么实际意义. 因为如果 data改变的话..最后的 sum并没有使用最新数据.而是上一次的刷新结果. 应该是哪里有脏数据.

@yesmeck 你给的例子并不能使用..因为data不能改变.
const data = [ { key: "1", name: "John Brown", age: 30, address: "New York No. 1 Lake Park", }, { key: "2", name: "Jim Green", age: 20, address: "London No. 1 Lake Park", }, { key: "3", name: "Joe Black", age: Math.random() * 20, address: "Sidney No. 1 Lake Park", }, ]; 例如如此修改...实际上最后的sum并不正确.

@yesmeck https://codesandbox.io/s/xjpkx9rzzw此演示有问题,当您将固定位置设置为左时,您会发现样式混乱。

我设法使用组件包装器做到了这一点,但是有点尴尬。 代码看起来像这样

export default class extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      localData: props.data,
    };

    this.tableRef = React.createRef();
  }

  handleTableUpdate = () => {
    this.setState({ localData: this.tableRef.current.getLocalData() });
  }

  render() {
    return (
      <Table
        ref={this.tableRef}
        columns={this.props.columns}
        dataSource={this.props.data}
        onChange={this.handleTableUpdate}
        components={{
          body: {
            wrapper: (props) => (
              <BodyWithSummary
                columns={this.props.columns}
                data={this.state.localData}
                {...props}
              />
            ),
          },
        }}
      />
    );
  }
}

function BodyWithSummary(props) {
  const { data, columns, ...otherProps } = props;
  return (
    <tbody {...otherProps}>
      <React.Fragment>
        {data && data.length > 0 && (
          <tr>
            {props.columns.map((col) => renderColumn(col, data))}
          </tr>
        )}
        {props.children}
      </React.Fragment>
    </tbody>
  );
}

令人讨厌的事情是,如果我想在过滤后的行上计算聚合数据,则需要调用getLocalData
如果主体包装将表ref作为prop接收,或者有一种更简单的方法来访问将要呈现的数据(props.children是反应节点列表,对计算聚合不是很有用),那就更好了。

我们可以使用footer prop但可以在表中呈现而不是其他div吗?

临时这样处理的:

20180927 0905

      .ant-table-footer {
        padding: 0;
      }
                                    footer={(currentPageData)=>{
                                        return (
                                            <Row style={{marginRight:17}}>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>合计</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4}>
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                            </Row>
                                        );
                                    }}

不是很完美咯。

期待columns的foot早日出来O(∩_∩)O

@ybning 你那个用固定列,会出问题吗?很多这种固定列都会出问题。。

@yesmeck您的示例中断了内部表计数: https : //codesandbox.io/s/rrpo02qwkq
导航至第2页,然后返回至第1页,它将在每个导航上复制数据。

这个问题有更新吗?

@linrf不,希望有人可以解决这个问题

我们可以添加一个total道具来处理聚合统计信息吗?
totalfooter
仅接受用于处理列数据的函数,默认值为reduce

v7a kvx 5cig rjeo 696g
我最后把合计放到column里了

antd 的 table footer 内容的渲染确实不太好用,尤其是表格本身有固定列的情况下。

可以换下方式,用两个 table 来实现,一个渲染原 table, 一个渲染底部 footer 元素。再配合样式覆盖,隐藏掉 table footer 的 thead 以及原 table 滚动区域的滚动条。最后再加入 JS 代码,让两个 table 的水平滚动位置对齐,基本就差不多了。

组件:

import React, { PureComponent } from 'react';
import { Table } from 'antd';
import styles from './index.less';

export default class ChartTable extends PureComponent {
  constructor(props) {
    super(props);

    this.refBox = React.createRef();
  }
  componentDidMount() {
    const tableList = Array.from(this.refBox.current.querySelectorAll('.ant-table-body'));
    this.tableList = tableList;
    tableList.forEach((table) => {
      table.addEventListener('scroll', this.handleTableScroll);
    });
  }
  componentWillUnmount() {
    this.tableList.forEach((table) => {
      table.removeEventListener('scroll', this.handleTableScroll);
    });
  }
  handleTableScroll = (e) => {
    const current = e.currentTarget;
    this.tableList.forEach((table) => {
      if (table !== current && table.scrollLeft !== current.scrollLeft) {
        table.scrollLeft = current.scrollLeft;
      }
    });
  }
  renderFooterTable = () => {
    const { columns, dataSource } = this.props;
    const dataList = [{
      department: '合计',
    }];
    return (
      <Table
        className={styles.footerTable}
        pagination={false}
        scroll={{ x: 'max-content' }}
        size="small"
        columns={columns}
        dataSource={dataList}
      />
    );
  }
  render() {
    return (
      <div ref={this.refBox}>
        <Table
          className={styles.mainTable}
          pagination={false}
          scroll={{ x: 'max-content', y: 350 }}
          size="small"
          columns={this.props.columns}
          dataSource={this.props.dataSource}
        />
        {this.renderFooterTable()}
      </div>
    );
  }
}

样式覆盖文件:

mainTable {
  :global {
    .ant-table-body::-webkit-scrollbar {
      display: none;
    }
  }  
}
.footerTable {
  border-top: 1px solid #e8e8e8;

  :global {
    thead {
      display: none;
    }
  }
}

+1希望有一种方法可以在页脚中显示列聚合。

可以使用component属性来实现。

const __Table = (totalsRow = initTotals(), key='tableKey') => ({
    className,
    style,
    children
}) => (
    <table className={className} style={style} key={key}>
        {children}
        <tfoot>
            <tr>
                // add tfoot td here
            </tr>
        </tfoot>
    </table>
);

const TableWithTFoot = ({allData, columns}) =>
    <Table
        dataSource={allData.data}
        columns={columns}
        pagination={false}
        components={{ table: __Table(allData.totals) }}
    />

@rororofff已为此问题资助5.00美元。


@piuccio根据您的想法,我用打字稿写它。

https://github.com/Arweil/antd-ext/blob/master/src/TableExt/TableExt.tsx

https://github.com/ant-design/ant-design/issues/5710#issuecomment -450855438

this.refBox = React.createRef();

我使用此版本包,运行此代码失败。
“ antd”:“ 2.13.14”,“ react”:“ 15.4.0”,“ react-dom”:“ 15.4.0”

错误信息
Uncaught TypeError: _react2.default.createRef is not a function at new EstimationReport (psReport.js?18c1:47) at eval (ReactCompositeComponent.js?063f:295) at measureLifeCyclePerf (ReactCompositeComponent.js?063f:75) at

@carvendy可能是导入react时的模块解析设置。 尝试改变

import from 'react';

到这个:

import * as react from 'react'

我做了一个组件,
利用了columns model来渲染footer
但目前还不支持滚动条,

import React from 'react';

class TableFooter extends React.Component {
  render() {
    const { dataSource, columns } = this.props;
    return (
      <table className="ant-table">
        <colgroup>
          {columns.map((colModel, index) => {
            return <col style={{
              width: colModel.width,
              minWidth: colModel.width
            }} key={index} />
          })}
        </colgroup>
        <tfoot >
          <tr >
            {columns.map((colum, idxCol) => {
              return <td style={{ padding: "0px 8px" }} className={colum.className} key={idxCol}>
                <strong>
                  {colum.footerContent ? colum.footerContent : (colum.footerSum ? dataSource.reduce((sum, record) => sum + parseFloat(record[colum.key]), 0) : "")}
                </strong>
              </td>
            })}
          </tr>
        </tfoot>
      </table>
    )
  }
}
export default TableFooter;

页面调用

...
render() {
  const columns = [
      {
        key: 'productName'
        footerContent: 'SUM:',
      },
      {
        key: 'quantity',
        footerSum: true,
      }
    }
];
return (
  <Table
    columns={columns}
    dataSource={dataSource}
    footer={()=> {
        return (
           <TableFooter dataSource={dataSource} columns={columns} />
        )
       }
    }
  />
)
....

var data = this.getLocalData();
var current;
var pageSize;
var state = this.state; // 如果没有分页的话,默认全部展示

  if (!this.hasPagination()) {
    pageSize = Number.MAX_VALUE;
    current = 1;
  } else {
    pageSize = state.pagination.pageSize;
    current = this.getMaxCurrent(state.pagination.total || data.length);
  } // 分页
  // ---
  // 当数据量少于等于每页数量时,直接设置数据
  // 否则进行读取分页数据


  if (data.length > pageSize || pageSize === Number.MAX_VALUE) {
    data = data.filter(function (_, i) {
      return i >= (current - 1) * pageSize && i < current * pageSize;
    });
  }

  return data;
}

这是table的处理数据的源码
能否在这里添加一个函数,计算列表数值的和,输出时添加data的汇总数,page和pagesize减下刚加的数据就好 @sorrycc

2年后,此问题仍然存在。

2年后,此问题仍然存在。

我自己原来在非分页表格里使用修改重写col的render并追加数据的方式来做到:

image

but 分页的情况下,如果多传数据会被干掉 https://github.com/ant-design/ant-design/blob/fee5e291632cce131611dd1a9e2ab89e02ee43a3/components/table/Table.tsx#L407

我想PR这个,但是怕自己API设计不符合老板 @afc163 的要求...

2年后,此问题仍然存在。

新表在路上。期待新表

https://github.com/ant-design/ant-design/issues/16911#issuecomment -523423460

@ alexchen1875没有提及与此相关的任何内容。

@ alexchen1875没有提及与此相关的任何内容。

仔细阅读表格部分的说明。

@ alexchen1875太棒了!

我想提交个PR,临时加个“允许data不裁剪数据”的props,来支持跳过https://github.com/ant-design/ant-design/blob/61e319b66826530a1882c20a41862a15d57b120a/components/table/Table.tsx#L408 的filter逻辑,使 https://github.com/ant-design/ant-design/issues/5710#issuecomment-524164125 在分页的情况下也可用,不知道团队会不会接受...

我修改了这个演示
增加了对固定列标题分组单元格合并滚动
我用\

和分页不会受到影响。在我的项目中临时使用

demo新的演示地址

用法:

const calcRow = [
    {
        colspan: 2,
        render: () => 'total'
    },
    {
        render: sum => sum('age')
    },
    {
        render: sum => sum('score')
    }
]

image

antd v4支持表summaryhttps :

image

https://ant.design/components/table/#components -table-demo-summary

antd v4 had supported Table summary: #21656

image

https://ant.design/components/table/#components-table-demo-summary

antd4支持了summary,不过我感觉这个summary还是要继续迭代,现在的使用方式虽然写法自由,但是同时带来的影响是代码过于繁琐,不太符合antd4越来越简单的初衷

常见的简单场景就是对于当前页面的数据进行summary,友好体验应该是在cloumn上直接配summary:true,那样代码会整洁、统一很多
复杂场景可以使用目前的使用summary总结栏

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

PeteAndersen picture PeteAndersen  ·  3评论

plandem picture plandem  ·  3评论

longzb picture longzb  ·  3评论

zhangchen2397 picture zhangchen2397  ·  3评论

drcmda picture drcmda  ·  3评论