效果
依赖
bash
$ yarn add xlsx
源码
css
.xlsx-wrap {
position: relative;
width: 100%;
height: 100%;
background-color: #fafafa;
.ant-tabs {
width: 100%;
height: 100%;
.ant-tabs-nav {
height: 50px;
padding: 0 10px;
margin-bottom: 0;
}
.ant-tabs-content-holder {
border-top: 1px solid #000000;
height: calc(100% - 50px);
.ant-tabs-content {
height: 100%;
.ant-tabs-tabpane {
height: 100%;
.table-container {
width: 100%;
height: 100%;
padding: 10px;
overflow: auto;
table {
border-top: 1px solid red;
border-left: 1px solid red;
border-collapse: collapse;
td {
border-bottom: 1px solid red;
border-right: 1px solid red;
padding: 5px 10px;
}
}
}
}
}
}
}
}
js
import './index.scss';
import {useCallback, useMemo, useRef, useState} from 'react';
import type {UploadRequestOption} from 'rc-upload/lib/interface';
import {Button, Flex, Tabs, Upload} from 'antd';
import {read, utils, WorkBook, writeFileXLSX} from 'xlsx';
function PreviewXLSX() {
const tableContainerRef = useRef<HTMLDivElement>(null);
const [workBook, setWorkBook] = useState<WorkBook>({
SheetNames: [],
Sheets: {},
});
const items = workBook.SheetNames
.map((d, i) => ({
key: `${i}`,
label: d,
children: <div className="table-container" ref={tableContainerRef} dangerouslySetInnerHTML={{__html: utils.sheet_to_html(workBook.Sheets[d])}}/>
}));
const fileUpload = async (options: UploadRequestOption) => {
const fileReader = new FileReader();
fileReader.readAsArrayBuffer(options.file as File);
fileReader.onload = e => {
const buffer = e.target!.result;
console.log(read(buffer));
setWorkBook({...workBook, ...read(buffer)});
};
};
const exportFile = useCallback(() => {
const table = tableContainerRef.current!.getElementsByTagName('TABLE')[0];
const wb = utils.table_to_book(table);
writeFileXLSX(wb, 'table_to_xlsx.xlsx');
}, [tableContainerRef]);
return (<>
<div className="xlsx-wrap">
<Tabs tabBarExtraContent={
<Flex justify="flex-end" align="center" gap={10}>
<Button onClick={exportFile}>导出</Button>
<Upload action="#" customRequest={fileUpload} showUploadList={false}>
<Button type="primary">点击上传</Button>
</Upload>
</Flex>
} items={useMemo(() => items, [items])}/>
</div>
</>);
}
export default PreviewXLSX;