ProTable - 高级表格 合并行,以及ProTable的用法
key React.key 确定这个列的唯一值,一般用于 dataIndex 重复的情况
dataIndex React.key | React.key[] 与实体映射的 key,数组会被转化 [a,b] => Entity.a.b
valueType ProFieldValueType 数据的渲染方式,我们自带了一部分,你也可以自定义 valueType
title ReactNode |(props,type,dom)=> ReactNode 标题的内容,在 form 中是 label
tooltip string 会在 title 旁边展示一个 icon,鼠标浮动之后展示
valueEnum (Entity)=> ValueEnum | ValueEnum 支持 object 和 Map,Map 是支持其他基础类型作为 key
fieldProps (form,config)=>fieldProps| fieldProps 传给渲染的组件的 props,自定义的时候也会传递
formItemProps (form,config)=>formItemProps | formItemProps 传递给 Form.Item 的配置
renderText (text: any, record: Entity, index: number, action: ProCoreActionType) => any 修改的数据是会被 valueType 定义的渲染组件消费
render (dom,entity,index, action, schema) => React.ReactNode 自定义只读模式的 dom,render 方法只管理的只读模式,编辑模式需要使用 renderFormItem
renderFormItem (schema,config,form) => React.ReactNode 自定义编辑模式,返回一个 ReactNode,会自动包裹 value 和 onChange
request (params,props) => Promise<{label,value}[]> 从远程请求网络数据,一般用于选择类组件
params Record<string, any> 额外传递给 request 的参数,组件不做处理,但是变化会引起request 重新请求数据
hideInForm boolean 在 Form 中隐藏
hideInTable boolean 在 Table 中隐藏
hideInSearch boolean 在 Table 的查询表单中隐藏
hideInDescriptions boolean 在 descriptions 中隐藏
rowProps RowProps 在开启 grid 模式时传递给 Row,仅在ProFormGroup, ProFormList, ProFormFieldSet 中有效
colProps ColProps 在开启 grid 模式时传递给 Col
password 密码输入框
money 金额输入框
textarea 文本域
date 日期
dateTime 日期时间
dateWeek 周
dateMonth 月
dateQuarter 季度输入
dateYear 年份输入
dateRange 日期区间
dateTimeRange 日期时间区间
time 时间
timeRange 时间区间
text 文本框
select 下拉框
treeSelect 树形下拉框
checkbox 多选框
rate 星级组件
radio 单选框
radioButton 按钮单选框
progress 进度条
percent 百分比组件
digit 数字输入框
second 秒格式化
avatar 头像
code 代码框
switch 开关
fromNow 相对于当前时间
image 图片
jsonCode 代码框,但是带了 json 格式化
color 颜色选择器
cascader 级联选择器
segmented 分段器
group 分组
formList 表单列表
formSet 表单集合
divider 分割线
dependency 依赖项
父子孙
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="父" />,
dataIndex: 'bcMeteringUnit',
valueType: 'text',
hideInSearch: true,
children: [
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="子" />,
dataIndex: 'bpcj',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.bpcj || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
children: [
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="孙" />,
dataIndex: 'bpcj',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.bpcj || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="孙" />,
dataIndex: 'jdSy',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.jdSy || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
},
],
},
合并行
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="产量(吨)" />,
dataIndex: 'keyParameter',
valueType: 'option',
hideInSearch: true,
width: 180,
render: (text: any, record: any, index: number) => {
let bpcjCl = record?.bpcjCl;
let xxcjCl = record?.xxcjCl;
return {
children:
index == 0
? [
'经典产量:' + bpcjCl,
// eslint-disable-next-line react/jsx-key
<br />,
'新型产量:' + xxcjCl,
]
: '',
props: {
rowSpan: index == 0 ? 3 : index == 3 ? 1 : 0,
colSpan: index === 3 ? 0 : 1,
},
};
},
},
源码
import DictTag, { DictValueEnumObj } from '@/components/DictTag';
import {
getReportDeviceMappingAll,
exportList,
} from '@/services/reportManager/EquipmentOfficeStatistics';
import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons';
import {
ActionType,
FooterToolbar,
PageContainer,
ProColumns,
ProTable,
ProFormInstance,
} from '@ant-design/pro-components';
import { FormattedMessage, useAccess, useIntl } from '@umijs/max';
import { Button, Modal, message, Tooltip } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import dayjs from 'dayjs';
import './index.scss';
import UpdateForm from './edit';
/**
* 下载文件
*
*
*/
function downloadFile(blob: any, fileName: string) {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName || 'exported_file';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
a.remove();
}
const MenuTableList: React.FC = () => {
// proTableFormRef
const proTableFormRef = useRef<ProFormInstance>();
const actionRef = useRef<ActionType>();
const access = useAccess();
const [startTime, setStartTime] = useState<string>('');
const [endTime, setEndTime] = useState<string>('');
/** 国际化配置 */
const intl = useIntl();
const [params, setParams] = useState<any>({});
const [modalVisible, setModalVisible] = useState<boolean>(false);
/**
* 导出数据
*
*
*/
const handleExport = async () => {
const hide = message.loading('正在导出');
try {
await exportList({ ...params })
.then((res) => {
if (res && res) {
downloadFile(res, '设备办统计报表_' + new Date().getTime() + '.xls');
}
})
.catch((err) => {
console.log(err);
});
hide();
message.success('导出成功');
return true;
} catch (error) {
hide();
message.error('导出失败,请重试');
return false;
}
};
const defaultTime = (value: any) => {
const tmp = new Date();
let month: any = tmp.getMonth();
if (`${month}`.length != 2) {
month = '0' + tmp.getMonth();
}
let date: any = tmp.getDate();
if (`${date}`.length != 2) {
date = '0' + tmp.getDate();
}
let start = tmp.getFullYear() + '-' + (month + 1);
let end = tmp.getFullYear() + '-' + (month + 1);
if (value == 'start') {
return start;
} else if (value == 'end') {
return end;
}
};
useEffect(() => {}, []);
const columns: ProColumns<API.System.Menu>[] = [
{
title: <FormattedMessage id="basicconfig.menu.menu_name" defaultMessage="项目" />,
dataIndex: 'name',
valueType: 'text',
hideInSearch: true,
width: 80,
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="单位" />,
dataIndex: 'unit',
valueType: 'text',
hideInSearch: true,
// hideInTable: true,
render: (text: any, record: any, index: number) => {
return {
children: record.unit || '',
props: {
colSpan: index === 3 ? 11 : 1,
},
};
},
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="父" />,
dataIndex: 'bcMeteringUnit',
valueType: 'text',
hideInSearch: true,
children: [
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="子" />,
dataIndex: 'bpcj',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.bpcj || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
children: [
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="孙" />,
dataIndex: 'bpcj',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.bpcj || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="孙" />,
dataIndex: 'jdSy',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.jdSy || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
},
],
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="子" />,
dataIndex: 'xxSc',
valueType: 'text',
hideInSearch: true,
// colSpan:index === 3?0:1,
render: (text: any, record: any, index: number) => {
return {
children: record.xxSc || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
children: [
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="孙" />,
dataIndex: 'xxSc',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.xxSc || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="孙" />,
dataIndex: 'xxSy',
valueType: 'text',
hideInSearch: true,
render: (text: any, record: any, index: number) => {
return {
children: record.xxSy || '',
props: {
colSpan: index === 3 ? 0 : 1,
},
};
},
},
],
},
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="产量(吨)" />,
dataIndex: 'keyParameter',
valueType: 'option',
hideInSearch: true,
width: 180,
render: (text: any, record: any, index: number) => {
let bpcjCl = record?.bpcjCl;
let xxcjCl = record?.xxcjCl;
return {
children:
index == 0
? [
'经典产量:' + bpcjCl,
// eslint-disable-next-line react/jsx-key
<br />,
'新型产量:' + xxcjCl,
]
: '',
props: {
rowSpan: index == 0 ? 3 : index == 3 ? 1 : 0,
colSpan: index === 3 ? 0 : 1,
},
};
},
},
{
title: <FormattedMessage id="basicconfig.menu.component" defaultMessage="选择月份" />,
dataIndex: 'dateTime',
valueType: 'dateMonth',
initialValue: dayjs(defaultTime('start'), 'YYYY-MM'),
hideInTable: true,
},
];
return (
<PageContainer>
<div style={{ width: '100%' }}>
<ProTable<API.System.Menu>
headerTitle={intl.formatMessage({
id: 'pages.searchTable.title',
defaultMessage: '信息',
})}
actionRef={actionRef}
formRef={proTableFormRef}
rowKey="menuId"
key="menuList"
pagination={false}
search={{
labelWidth: 120,
}}
bordered
toolbar={{
settings: [], //列设置(刷新,密度,列设置)
}}
toolBarRender={() => [
// hidden={!access.hasPerms('system:dept:export')}
<Button
type="primary"
key="export"
onClick={async () => {
setModalVisible(true);
}}
>
配置
</Button>,
<Button
type="primary"
key="export"
onClick={async () => {
handleExport();
}}
>
<FormattedMessage id="pages.searchTable.export" defaultMessage="导出" />
</Button>,
]}
request={(params) =>
getReportDeviceMappingAll({ ...params }).then((res) => {
setParams(params);
let dataList: any = [];
if (res.code == 200) {
let data = res.data;
dataList = [
{
name: '水',
unit: 'm³',
bpcj: data.bpcjYlW,
xxSc: data.xxScYlW,
xxSy: data.xxSyYlW,
gfYl: data.gfYlW,
fscYl: data.fscYlW,
total: data.totalW,
dj: data.djW,
je: data.jeW,
dh: data.dhW,
xs: data.xsW,
zhNh: data.zhNh,
bpcjCl: data.bpcjCl,
xxcjCl: data.xxcjCl,
jdSy: data.bpcjSyYlW,
},
{
name: '电',
unit: 'kW.h',
bpcj: data.bpcjYlE,
xxSc: data.xxScYlE,
xxSy: data.xxSyYlE,
gfYl: data.gfYlE,
fscYl: data.fscYlE,
total: data.totalE,
dj: data.djE,
je: data.jeE,
dh: data.dhE,
xs: data.xsE,
zhNh: data.zhNh,
bpcjCl: data.bpcjCl,
xxcjCl: data.xxcjCl,
jdSy: data.bpcjSyYlE,
},
{
name: '天然气',
unit: 'm³',
bpcj: data.bpcjYlG,
xxSc: data.xxScYlG,
xxSy: data.xxSyYlG,
gfYl: data.gfYlG,
fscYl: data.fscYlG,
total: data.totalG,
dj: data.djG,
je: data.jeG,
dh: data.dhG,
xs: data.xsG,
zhNh: data.zhNh,
bpcjCl: data.bpcjCl,
xxcjCl: data.xxcjCl,
jdSy: data.bpcjSyYlG,
},
{
name: '说明',
unit: ' ',
bpcj: ' ',
xxSc: ' ',
xxSy: ' ',
gfYl: ' ',
fscYl: ' ',
total: ' ',
dj: ' ',
je: ' ',
dh: ' ',
xs: ' ',
zhNh: ' ',
bpcjCl: ' ',
xxcjCl: ' ',
jdSy: '',
},
];
setStartTime(data.startTime);
setEndTime(data.endTime);
}
return {
data: dataList,
success: true,
};
})
}
columns={columns}
/>
</div>
<div style={{ background: '#ffffff', padding: '0 20px' }}>
<div style={{ textAlign: 'right', lineHeight: '40px' }}>
本次报表统计期间:{startTime}—{endTime}
</div>
<div className="flex">
<div>制表人:</div>
<div>部门负责人:</div>
</div>
</div>
{modalVisible && (
<UpdateForm
onSubmit={async (values) => {
console.log(values);
setModalVisible(false);
}}
onCancel={() => {
setModalVisible(false);
}}
open={modalVisible}
/>
)}
</PageContainer>
);
};
export default MenuTableList;