ProTable - 高级表格
ProTable 的诞生是为了解决项目中需要写很多 table 的样板代码的问题,所以在其中做了封装了很多常用的逻辑。这些封装可以简单的分类为预设行为与预设逻辑。
依托于 ProForm 的能力,ProForm 拥有多种形态,可以切换查询表单类型,设置变形成为一个简单的 Form 表单,执行新建等功能。
但是没有打印功能。所以自己写了个通用打印组件。
components/FrPrint/index.less
.backgroud {
width: 100%;
height: 700px;
//background-color: rgb(66, 66, 66);
}
components/FrPrint/index.tsx
import React, { useRef } from 'react';
import { Modal } from 'antd';
import { useReactToPrint } from "react-to-print";
import csstyle from "./index.less";
import moment from 'moment';
import ProTable from '@ant-design/pro-table';
import { WaterMark } from '@ant-design/pro-layout';
import { useModel } from 'umi';
export type FormValueType = {
target?: string;
template?: string;
type?: string;
time?: string;
frequency?: string;
};
export type UpdateFrPrintProps = {
title?: string;
subTitle?: string;
columns: any[];
dataSource: any[];
onCancel: (flag?: boolean, formVals?: FormValueType) => void;
printModalVisible: boolean;
};
/**
* ProTable - 高级表格 通用打印模块
*/
const FrPrint: React.FC<UpdateFrPrintProps> = (props) => {
const { initialState } = useModel('@@initialState');
const componentRef = useRef();
const handlePrint = useReactToPrint({
content: () => (componentRef.current != undefined) ? componentRef.current : null,
onBeforeGetContent: () => (props.onCancel())
});
//console.log('columns', props.columns);
const date = moment().format('YYYY-MM-DD HH:mm:ss').toString();
return (
<Modal
width="80%"
centered
destroyOnClose
title={false}
visible={props.printModalVisible}
okText="打印"
onCancel={() => {
props.onCancel();
}}
onOk={() => {
handlePrint();//打印
}}
keyboard={true}
>
<div className={csstyle.backgroud} ref={componentRef}>
<WaterMark content={initialState?.currentUser?.name}>
<div style={{ padding: 30 }}>
<div style={{ width: '100%', textAlign: "center", color: '#aaaaaa' }}>西藏大麦 · Dmart</div>
<h3 style={{ width: '100%', textAlign: "center" }}>{props.title}</h3>
<h4>{props.subTitle}</h4>
{/* 普通 Table columns 不支持 valueType 属性
<Table className={csstyle.table} columns={props.columns} dataSource={props.dataSource} pagination={false} bordered size="small" />
*/}
<ProTable<any>
columns={props.columns}
dataSource={props.dataSource}
rowKey="key"
pagination={false}
search={false}
toolBarRender={false}
bordered size="small"
/>
<div style={{ width: '100%', paddingTop: 30, textAlign: "center", color: '#aaaaaa', fontSize: 10 }}>打印日期:{date}</div>
</div>
</WaterMark>
</div>
</Modal >
);
};
export default FrPrint;
调用方法
1.引用模块
import FrPrint from "../components/FrPrint";
2.ProTable toolBarRender属性中设置打印按钮
toolBarRender={() => [
<Button key="out">
导出
</Button>,
/// 设置打印按钮
<Button key="out"
onClick={() => handlePrintModalVisible(true)}
>打印
</Button>
]}
3.PageContainer中加入组件
{/* 调用打印模块 */}
<FrPrint
title={tableName}
subTitle={paramsText}
columns={columns}
dataSource={[...selectedRowsState, sumRow]}
onCancel={() => {
handlePrintModalVisible(false);
}}
printModalVisible={printModalVisible}
/>
完整调用Demo
regionSum/index.tsx
import React, { useState } from 'react';
import { Button } from 'antd';
import { PageContainer } from '@ant-design/pro-layout';
import type { ProColumns } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import { getList } from './service';
import type { TableListItem } from './data';
import FrPrint from "../components/FrPrint";
import restyle from '../style.less';
const TableList: React.FC = () => {
const [sortState, setSortState] = useState<boolean>(false);
const [printModalVisible, handlePrintModalVisible] = useState<boolean>(false);
const [paramsText, setParamsText] = useState<string>('');
const [selectedRowsState, setSelectedRows] = useState<TableListItem[]>([]);
const [sumRow, setSumRow] = useState<TableListItem>();
const tableName = "区域销售汇总";
/** 查询表单 */
const query: ProColumns<TableListItem>[] = [
{
title: '日期区间',
key: 'dateRange',
dataIndex: 'createdAtRange',
valueType: 'dateRange',
hideInTable: true,
//initialValue: [moment(), moment().add(1, 'day')],
initialValue: ['2021-01-01', '2021-01-31'],
}
]
/** 表格列设置 */
const columns: ProColumns<TableListItem>[] = [
{
title: '销售区域',
dataIndex: 'Region',
hideInSearch: true,
},
{
title: '实销金额',
dataIndex: 'SSS',
align: 'right',
valueType: 'money',
hideInSearch: true,
sorter: (a, b) => a.SSS - b.SSS,
},
{
title: '毛利金额',
dataIndex: 'SML',
align: 'right',
valueType: 'money',
hideInSearch: true,
sorter: (a, b) => a.SML - b.SML,
},
{
title: '毛利率',
dataIndex: 'MLL',
align: 'right',
valueType: 'percent',
hideInSearch: true,
sorter: (a, b) => a.MLL - b.MLL,
},
];
/** 表格列含查询表单 */
const proColumns: ProColumns<TableListItem>[] = [
...query,
...columns
];
return (
<PageContainer
header={{
breadcrumb: {},
}}>
<ProTable<TableListItem>
headerTitle={tableName}
toolBarRender={() => [
<Button key="out">
导出
</Button>,
/// 设置打印按钮
<Button key="out"
onClick={() => handlePrintModalVisible(true)}
>打印
</Button>
]}
pagination={false}
size="small"
rowKey="key"
search={{
labelWidth: 120,
}}
request={getList}
onSubmit={(params) => {
//console.log('onSubmit.params', params);
let tmp: string = "";
if (params.dateRange != undefined && params.dateRange.length == 2) {
tmp += ' 日期区间:' + params.dateRange[0] + " - " + params.dateRange[1]
}
setParamsText(tmp)
}}
onChange={(pagination, filters, sorter, extra) => {
if (Object.keys(extra).length > 0) {
console.log("onChange.extra", extra);
setSortState(true);//标记为排序操作状态
setSelectedRows(extra.currentDataSource);
}
}}
onDataSourceChange={(data) => {
console.log('onDataSourceChange.data', data);
//如果是排序操作,则不处理数据
if (!sortState) {
setSelectedRows(data);//获取表格数据
///-------------------------计算汇总-----------------------------
let totalSSS: number = 0;
let totalSML: number = 0;
data.forEach(({ SSS, SML }) => {
totalSSS += Number(SSS);
totalSML += Number(SML);
});
const totalMll = totalSSS == 0 ? 0 : Number(totalSML / totalSSS * 100)
const totalRow: TableListItem = { 'Region': '合计', 'SSS': totalSSS, 'SML': totalSML, 'MLL': totalMll }
setSumRow(totalRow);//获取合计行数据
}
}}
columns={proColumns}
columnsState={{
onChange: (value) => {
console.log('column state', value);
},
}}
///增加合计行
summary={() => {
return sumRow != undefined ? (
<ProTable.Summary.Row className={restyle.totleRow}>
<ProTable.Summary.Cell index={0}>合计:</ProTable.Summary.Cell>
<ProTable.Summary.Cell index={1}>
<span className={restyle.totle}>{(sumRow.SSS).toFixed(2)}</span>
</ProTable.Summary.Cell>
<ProTable.Summary.Cell index={2}>
<span className={restyle.totle}>{(sumRow.SML).toFixed(2)}</span>
</ProTable.Summary.Cell>
<ProTable.Summary.Cell index={3}>
<span className={restyle.totle}>{(sumRow.MLL).toFixed(2)}%</span>
</ProTable.Summary.Cell>
</ProTable.Summary.Row>
) : '';
}}
/>
{/* 调用打印模块 */}
<FrPrint
title={tableName}
subTitle={paramsText}
columns={columns}
dataSource={[...selectedRowsState, sumRow]}
onCancel={() => {
handlePrintModalVisible(false);
}}
printModalVisible={printModalVisible}
/>
</PageContainer >
);
};
export default TableList;