react / antd ProTable - 高级表格 合并行,子表头

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

在这里插入图片描述
valueType 列表

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;

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
合并单元格,需要使用 `react-bootstrap-table-next` 中的 `rowSpan` 和 `colSpan` 属性。这些属性可以在 `columns` 对象中定义,用于指定表格中每个单元格应该跨越的和列的数量。 具体的实现步骤如下: 1. 在 `columns` 对象中定义需要合并单元格的列,为其添加 `rowSpan` 和 `colSpan` 属性。 2. 在 `data` 数组中为需要合并单元格的添加相应的属性值,这些属性值将在表格渲染时被引用。 下面是一个例: ```javascript import BootstrapTable from 'react-bootstrap-table-next'; import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css'; const columns = [ { dataField: 'id', text: 'ID', }, { dataField: 'name', text: 'Name', }, { dataField: 'age', text: 'Age', }, { dataField: 'gender', text: 'Gender', rowSpan: 2, // 跨越两 }, { dataField: 'location', text: 'Location', colSpan: 2, // 跨越两列 }, { dataField: 'address', text: 'Address', hidden: true, // 隐藏该列 }, { dataField: 'city', text: 'City', }, { dataField: 'state', text: 'State', }, ]; const data = [ { id: 1, name: 'John', age: 30, gender: 'Male', location: 'New York', address: '123 Main St', city: 'New York', state: 'NY', }, { id: 2, name: 'Jane', age: 25, gender: 'Female', location: 'San Francisco', address: '456 Elm St', city: 'San Francisco', state: 'CA', }, ]; <BootstrapTable keyField='id' data={ data } columns={ columns }/> ``` 在上面的例中,表格中的 `Gender` 列跨越了两,`Location` 列跨越了两列。注意,在定义了 `colSpan` 属性的列后面应该添加相应数量的列来占据跨度。 希望这可以帮助你实现合并单元格的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sunny

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值