效果
依赖
$ yarn add xlsx
源码
.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;
}
}
}
}
}
}
}
}
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;