React中如何将Base64格式Excel转为可视图层展示?
在React中渲染Base64格式的Excel文件
问题背景
我有Base64字符串格式的文件数据和对应的文件类型,示例如下:
FileData = "UEsDBBQABgAIAAAAI"
FileType = "application/msexcel"
目前我用react-doc-viewer包实现渲染,先把Base64转成Blob再生成URL传入组件,代码如下:
function renderPOXLSExcelFile(fileData: any, fileType: any) { // Convert base64 file data back to a Blob const binary = atob(fileData.split(',')[1]); const array = []; for (let i = 0; i < binary.length; i++) { array.push(binary.charCodeAt(i)); } const blob = new Blob([new Uint8Array(array)], { type: fileType }); // Create URL from blob const url = URL.createObjectURL(blob); const docs = [{ uri: url, fileType: fileType }]; return ( <> <DocViewer documents={docs} config={{header: {disableHeader: false}}} pluginRenderers={DocViewerRenderers /> </> ); }
我确认react-doc-viewer可以接收该URL展示Excel,但想了解其他从Blob渲染Excel的方法。之前试过把Excel解析成JSON再加样式,UI效果很差,求解决方案。
可选解决方案
1. 使用SheetJS(xlsx)结合成熟表格组件
SheetJS可解析Blob格式的Excel,搭配react-table、antd Table这类专业表格组件渲染,能直接复用组件的样式、分页、排序等功能,避免自己写样式的麻烦:
import * as XLSX from 'xlsx'; import { Table } from 'antd'; import { useState, useEffect } from 'react'; function renderExcelWithSheetJS(blob: Blob) { const [dataSource, setDataSource] = useState([]); const [columns, setColumns] = useState([]); useEffect(() => { const reader = new FileReader(); reader.onload = (e) => { const data = new Uint8Array(e.target?.result as ArrayBuffer); const workbook = XLSX.read(data, { type: 'array' }); const firstSheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[firstSheetName]; const jsonData = XLSX.utils.sheet_to_json(worksheet); // 自动生成表格列配置 const cols = Object.keys(jsonData[0] || {}).map(key => ({ title: key, dataIndex: key, key: key })); setDataSource(jsonData); setColumns(cols); }; reader.readAsArrayBuffer(blob); }, [blob]); return <Table dataSource={dataSource} columns={columns} bordered />; }
2. 使用iframe直接渲染
利用浏览器内置的Excel预览能力,把Blob URL放入iframe中,实现简单的预览效果:
function renderExcelWithIframe(blobUrl: string) { return ( <iframe src={blobUrl} width="100%" height="600px" title="Excel Preview" style={{ border: '1px solid #eee' }} /> ); }
这种方式优点是代码极简,缺点是预览样式受浏览器限制,无法自定义控制。
3. 使用react-excel-renderer库
该库封装了Excel解析和基础渲染逻辑,可在此基础上自定义样式,比自己解析JSON再写样式高效:
import { ExcelRenderer } from 'react-excel-renderer'; import { useState, useEffect } from 'react'; function renderExcelWithRenderer(blob: Blob) { const [tableData, setTableData] = useState(null); const [cols, setCols] = useState(null); useEffect(() => { ExcelRenderer(blob, (err, resp) => { if (err) { console.error(err); } else { setCols(resp.cols); setTableData(resp.rows); } }); }, [blob]); if (!tableData || !cols) return null; return ( <table border="1" cellPadding="8" cellSpacing="0" style={{ width: '100%', borderCollapse: 'collapse', marginTop: '16px' }} > <thead> <tr> {cols.map((col: any, idx: number) => ( <th key={idx} style={{ backgroundColor: '#f5f5f5', textAlign: 'left' }}>{col.name}</th> ))} </tr> </thead> <tbody> {tableData.map((row: any, idx: number) => ( <tr key={idx} style={{ backgroundColor: idx % 2 === 0 ? '#fff' : '#fafafa' }}> {row.map((cell: any, cellIdx: number) => ( <td key={cellIdx}>{cell}</td> ))} </tr> ))} </tbody> </table> ); }
通用注意事项
- 组件卸载时务必调用
URL.revokeObjectURL(blobUrl),避免内存泄漏。 - 旧版Excel格式(.xls)的兼容性不如新版(.xlsx),需要提前测试验证。
内容的提问来源于stack exchange,提问作者Animesh Ashish
相关产品推荐
相关产品推荐

