React.js中React-Bootstrap-Table列求和及条件格式设置技术咨询
解决方案:实现React Data Table的三个需求
我来帮你搞定这三个需求,咱们一步步修改代码来实现:
1. 先修复基础问题
首先得调整原代码里的几个小问题,不然后续计算会出问题:
state字段(对应Amount列)原本是字符串,计算总和/平均值前要转成数字类型- HTML里有两个
id="root"的div,得改成不同的id(比如把显示总和的区域改成table-root和单独的总和展示元素) - 脚本里错误引入了Bootstrap CSS文件,要删掉这个无效的script标签
2. 实现实时计算列总和(搜索时更新)
我们需要把组件改成类组件,维护过滤后的数据状态,这样每次搜索框内容变化时,就能基于过滤后的数据计算总和:
- 使用
onFilterChange回调获取过滤后的数据 - 维护
filteredData状态,每次过滤更新时同步 - 基于
filteredData计算Amount列的总和并实时更新到页面
3. 添加条件格式
通过列的cellFormat函数,根据数值和当前数据集的平均值、最大值比较,给单元格添加对应的CSS类,实现颜色区分:
- 先计算过滤后数据的平均值和最大值
- 在
cellFormat里判断当前数值属于哪个区间,返回带样式的元素 - 定义对应的CSS样式来实现颜色效果
4. 数字字段右对齐
直接给Amount列添加className: 'text-right'(借助Bootstrap的内置类),或者用自定义style实现右对齐
完整修改后的代码
HTML部分
<title>React Table</title> <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css'> <link rel='stylesheet prefetch' href='https://cdn.rawgit.com/carlosrocha/react-data-components/v1.0.0/css/table-twbs.css'> <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css'> <style> /* 条件格式的自定义样式 */ .amount-green { color: green; } .amount-yellow { color: goldenrod; } .amount-orange { color: orange; } .amount-red { color: red; } </style> <body> <br> <h3> Area</h3> <br> <div id="table-root"></div><br> <h3> Sum: <span id="sum-value"></span></h3> <br> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <script src="https://npmcdn.com/react-data-components@1.0.1/dist/react-data-components.min.js"></script> <script> // React组件代码放在这里 </script> </body>
React组件代码
var DataTable = ReactDataComponents.DataTable; // Generate random data var names = ['201801003', '201801002', '201801004', '201801005', '201801006']; var cities = ['2018', '2017', '2017', '2017', '2017', '2017']; var addresses = ['Travancore', 'Sivagangai', 'Pudhukottai', 'Madurai']; var states = ['1200', '350', '6400', '1700', '750']; var data = []; for (var i = 0; i < 1000; i++) { data.push({ id: i, name: names[~~(Math.random() * names.length)], city: cities[~~(Math.random() * cities.length)], address: addresses[~~(Math.random() * addresses.length)], // 转成数字类型,方便后续计算 state: Number(states[~~(Math.random() * states.length)]) }); } class TableWithSum extends React.Component { constructor(props) { super(props); this.state = { filteredData: props.initialData }; this.handleFilterChange = this.handleFilterChange.bind(this); } handleFilterChange(filteredData) { // 更新过滤后的数据状态 this.setState({ filteredData }); // 计算总和并更新到页面 const total = filteredData.reduce((sum, item) => sum + item.state, 0); document.getElementById('sum-value').textContent = total.toLocaleString(); } render() { const { filteredData } = this.state; // 计算平均值和最大值(用于条件格式判断) const totalAmount = filteredData.reduce((sum, item) => sum + item.state, 0); const average = filteredData.length > 0 ? totalAmount / filteredData.length : 0; const maxAmount = filteredData.length > 0 ? Math.max(...filteredData.map(item => item.state)) : 0; var columns = [ { title: 'CID', prop: 'name' }, { title: 'Area', prop: 'city' }, { title: 'Authority', prop: 'address' }, { title: 'Amount', prop: 'state', className: 'text-right', // 借助Bootstrap类实现右对齐 cellFormat: (value) => { let className = ''; // 自定义条件判断逻辑,你可以根据需求调整阈值 if (value < average) { className = 'amount-green'; } else if (Math.abs(value - average) <= average * 0.1) { // 差值在平均值10%以内算"接近" className = 'amount-yellow'; } else if (value < maxAmount) { className = 'amount-orange'; } else { className = 'amount-red'; } return <span className={className}>{value.toLocaleString()}</span>; } } ]; return ( <DataTable className='container' keys='id' columns={columns} initialData={this.props.initialData} initialPageLength={5} initialSortBy={{ prop: 'city', order: 'descending' }} pageLengthOptions={[5, 20, 50]} onFilterChange={this.handleFilterChange} /> ); } } ReactDOM.render( <TableWithSum initialData={data} />, document.getElementById("table-root") ); // 页面初始化时计算初始总和 const initialTotal = data.reduce((sum, item) => sum + item.state, 0); document.getElementById('sum-value').textContent = initialTotal.toLocaleString();
关键说明
- 实时总和计算:通过
onFilterChange回调捕获搜索过滤后的数据集,每次过滤都重新计算总和并更新到页面 - 条件格式:我定义了"接近平均值"为与平均值的差值在10%以内,你可以根据业务需求调整这个阈值
- 右对齐:直接复用Bootstrap的
text-right类,也可以用style: { textAlign: 'right' }实现自定义右对齐
内容的提问来源于stack exchange,提问作者Maju
相关产品推荐
相关产品推荐

