perf: 订单>子维度: 表格导出

feature/pivot
Lei OT 2 years ago
parent e34f769723
commit 150b42418f

@ -1,5 +1,8 @@
import { Tag } from 'antd'; import { useState, useEffect } from "react";
import { CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons'; import { Tag, Button, message } from 'antd';
import { CaretUpOutlined, CaretDownOutlined, DownloadOutlined } from '@ant-design/icons';
import { utils, writeFile } from "xlsx";
import { isEmpty } from "../utils/commons";
/** /**
* @property diffPercent * @property diffPercent
@ -24,3 +27,49 @@ export const VSTag = (props) => {
</span> </span>
); );
}; };
/**
* 导出表格数据存为xlsx
*/
export const TableExportBtn = (props) => {
const output_name = `${props.label}`;
const [columnsMap, setColumnsMap] = useState([]);
useEffect(() => {
const flatCols = props.columns.flatMap((v, k) => (v.children ? v.children.map((vc) => ({ ...vc, title: `${v.title}-${vc.title}` })) : v)).filter(c => c.title);
setColumnsMap(flatCols);
return () => {};
}, [props.columns]);
const onExport = () => {
if (isEmpty(props.dataSource)) {
message.warning('无结果.');
return false;
}
const data = props.dataSource.map((item) => {
const itemMapped = columnsMap.reduce((sv, kset) => {
const render_val = typeof kset?.render === 'function' ? kset.render('', item) : null;
const data_val = kset?.dataIndex ? item[kset.dataIndex] : undefined;
const v = { [kset.title]: render_val || data_val };
return { ...sv, ...v };
}, {});
return itemMapped;
});
const ws = utils.json_to_sheet(data, { header: columnsMap.filter((r) => r.dataIndex).map((r) => r.title) });
const wb = utils.book_new();
utils.book_append_sheet(wb, ws, 'sheet');
writeFile(wb, `${output_name}.xlsx`);
};
return (
<Button
type="link"
icon={<DownloadOutlined />}
size="small"
disabled={false}
onClick={onExport}
>
导出excel
</Button>
);
};

@ -1,4 +1,4 @@
import React, { useContext, useEffect } from "react"; import React, { useContext, useEffect, useState } from "react";
import { Row, Col, Tabs, Table, Divider } from "antd"; import { Row, Col, Tabs, Table, Divider } from "antd";
import { ContainerOutlined } from "@ant-design/icons"; import { ContainerOutlined } from "@ant-design/icons";
import { stores_Context } from "../config"; import { stores_Context } from "../config";
@ -10,6 +10,7 @@ import * as config from "../config";
import { utils, writeFileXLSX } from "xlsx"; import { utils, writeFileXLSX } from "xlsx";
import DateGroupRadio from '../components/DateGroupRadio'; import DateGroupRadio from '../components/DateGroupRadio';
import SearchForm from './../components/search/SearchForm'; import SearchForm from './../components/search/SearchForm';
import { TableExportBtn } from './../components/Data';
const Orders_sub = () => { const Orders_sub = () => {
const { ordertype, ordertype_sub, ordertype_title } = useParams(); const { ordertype, ordertype_sub, ordertype_title } = useParams();
@ -175,61 +176,11 @@ const Orders_sub = () => {
const table_data_p = format_data(orders_store.orderCountData_Form_sub.ordercount1); const table_data_p = format_data(orders_store.orderCountData_Form_sub.ordercount1);
const table_data2_p = format_data(orders_store.orderCountData_Form_sub.ordercount2); const table_data2_p = format_data(orders_store.orderCountData_Form_sub.ordercount2);
return (
<div>
<Row gutter={{ sm: 16, lg: 32 }}>
<Col md={24} lg={12} xxl={14}>
<NavLink to={`/orders`}>返回</NavLink>
</Col>
<Col className="gutter-row" span={24}>
<SearchForm
defaultValue={{
initialValue: {
...date_picker_store.formValues,
...orders_store.searchValues,
},
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'dates'],
fieldProps: {
DepartmentList: { show_all: false },
WebCode: { show_all: true },
// dates: { hide_vs: true },
},
}}
onSubmit={(_err, obj, form, str) => {
orders_store.setSearchValues(obj, form);
orders_store.getOrderCount_type(ordertype, ordertype_sub);
orders_store.getOrderCountByType_sub(ordertype, ordertype_sub, orders_store.active_tab_key_sub);
}}
/>
</Col>
<Col span={24} style={{textAlign: 'right'}}>
<DateGroupRadio
visible={data_source.length!==0}
dataRaw={orders_store.orderCountDataRaw_type}
onChange={orders_store.onChangeDateGroupSub}
value={orders_store.orderCount_type_dateRadio.lineChartXGroup}
dataMapper={orders_store.orderCount_type_dateRadio.orderCountDataMapper}
fieldMapper={orders_store.orderCount_type_dateRadio.orderCountDataFieldMapper}
/>
</Col>
</Row>
<Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
<Col className="gutter-row" span={24}>
<Line {...line} />
</Col>
<Col className="gutter-row" span={24}> const tab_items = [
<Tabs activeKey={orders_store.active_tab_key_sub} onChange={active_key => orders_store.onChange_Tabs_sub(ordertype, ordertype_sub, active_key)}> {
<Tabs.TabPane key: 'detail', label: <span><ContainerOutlined />订单内容</span>, title: '订单内容',
tab={ children: (<Row>
<span>
<ContainerOutlined />
订单内容
</span>
}
key="detail">
<Row>
<Col span={24}> <Col span={24}>
{date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)} {date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)}
<Table <Table
@ -277,17 +228,9 @@ const Orders_sub = () => {
}} }}
/> />
</Col> </Col>
</Row> </Row>),
</Tabs.TabPane> },
<Tabs.TabPane { key: 'page', label: <span><ContainerOutlined />访问路径</span>, title: '访问路径',children: (<Row>
tab={
<span>
<ContainerOutlined />
访问路径
</span>
}
key="page">
<Row>
<Col span={24}> <Col span={24}>
{date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)} {date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)}
<Table dataSource={table_data_p.dataSource} rowKey={record => record.key} columns={table_data_p.columns} size="small" /> <Table dataSource={table_data_p.dataSource} rowKey={record => record.key} columns={table_data_p.columns} size="small" />
@ -297,17 +240,8 @@ const Orders_sub = () => {
{date_picker_store.start_date_cp ? date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "~" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) : ""} {date_picker_store.start_date_cp ? date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "~" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) : ""}
<Table dataSource={table_data2_p.dataSource} rowKey={record => record.key} columns={table_data2_p.columns} size="small" /> <Table dataSource={table_data2_p.dataSource} rowKey={record => record.key} columns={table_data2_p.columns} size="small" />
</Col> </Col>
</Row> </Row>)},
</Tabs.TabPane> { key: 'page_cxstate1', label: <span><ContainerOutlined />访问路径成行</span>, title: '访问路径(成行)',children: (<Row>
<Tabs.TabPane
tab={
<span>
<ContainerOutlined />
访问路径成行
</span>
}
key="page_cxstate1">
<Row>
<Col span={24}> <Col span={24}>
{date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)} {date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)}
<Table dataSource={table_data_p.dataSource} rowKey={record => record.key} columns={table_data_p.columns} size="small" /> <Table dataSource={table_data_p.dataSource} rowKey={record => record.key} columns={table_data_p.columns} size="small" />
@ -317,9 +251,76 @@ const Orders_sub = () => {
{date_picker_store.start_date_cp ? date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "~" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) : ""} {date_picker_store.start_date_cp ? date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "~" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) : ""}
<Table dataSource={table_data2_p.dataSource} rowKey={record => record.key} columns={table_data2_p.columns} size="small" /> <Table dataSource={table_data2_p.dataSource} rowKey={record => record.key} columns={table_data2_p.columns} size="small" />
</Col> </Col>
</Row>)},
];
const [propsForExport, setPropsForExport] = useState(tab_items[0]);
const tabItemsMapped = tab_items.reduce((r, v) => ({...r, [v.key]: v}), {});
const onTabsChange = (active_key) => {
setPropsForExport(tabItemsMapped[active_key]);
orders_store.onChange_Tabs_sub(ordertype, ordertype_sub, active_key);
};
return (
<div>
<Row gutter={{ sm: 16, lg: 32 }}>
<Col md={24} lg={12} xxl={14}>
<NavLink to={`/orders`}>返回</NavLink>
</Col>
<Col className="gutter-row" span={24}>
<SearchForm
defaultValue={{
initialValue: {
...date_picker_store.formValues,
...orders_store.searchValues,
},
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'dates'],
fieldProps: {
DepartmentList: { show_all: false },
WebCode: { show_all: true },
// dates: { hide_vs: true },
},
}}
onSubmit={(_err, obj, form, str) => {
orders_store.setSearchValues(obj, form);
orders_store.getOrderCount_type(ordertype, ordertype_sub);
orders_store.getOrderCountByType_sub(ordertype, ordertype_sub, orders_store.active_tab_key_sub);
}}
/>
</Col>
<Col span={24} style={{ textAlign: 'right' }}>
<DateGroupRadio
visible={data_source.length !== 0}
dataRaw={orders_store.orderCountDataRaw_type}
onChange={orders_store.onChangeDateGroupSub}
value={orders_store.orderCount_type_dateRadio.lineChartXGroup}
dataMapper={orders_store.orderCount_type_dateRadio.orderCountDataMapper}
fieldMapper={orders_store.orderCount_type_dateRadio.orderCountDataFieldMapper}
/>
</Col>
</Row> </Row>
</Tabs.TabPane>
</Tabs> <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
<Col className="gutter-row" span={24}>
<Line {...line} />
</Col>
<Col className="gutter-row" span={24}>
<Tabs
activeKey={orders_store.active_tab_key_sub}
onChange={onTabsChange}
tabBarExtraContent={{
right: (
<TableExportBtn
label={propsForExport.title}
{...(orders_store.active_tab_key_sub === 'detail'
? { columns: table_data.columns, dataSource: table_data.dataSource }
: { columns: table_data_p.columns, dataSource: table_data_p.dataSource })}
/>
),
}}
items={tab_items}
/>
</Col> </Col>
</Row> </Row>
</div> </div>

Loading…
Cancel
Save