React中如何上传并读取.csv、.xls和.xlsx文件?
问题:如何读取上传的.xls/.xlsx文件(类似处理.csv的方式)
我现在可以用react-file-reader和base-64实现读取.csv文件的功能,代码如下:
onFileUpload(file) { var decodedData = base64.decode(file.base64); }
<ReactFileReader fileTypes={[".csv",".xls", ".xlsx"]} base64={true} multipleFiles={false} handleFiles={this.onFileUpload}> <button className='btn'>Upload</button> </ReactFileReader>
但目前仅支持.csv文件,请问能否用类似处理.csv的方式读取.xls和.xlsx文件?或者有其他合适的模块可以实现?
解决方案
嘿,这个问题我刚好有经验!直接用base64解码.xls/.xlsx肯定不行的,因为它们是二进制格式的文件,不像.csv是纯文本,解码后只会得到一堆乱码。不过有非常成熟的前端方案可以解决这个问题,我给你详细说下:
推荐使用SheetJS(xlsx库)
这是前端处理Excel文件最常用的库之一,能完美兼容.xls和.xlsx格式,还支持将表格数据转换成CSV、JSON等你需要的格式,用法也很简单。
步骤1:安装依赖
首先在你的项目里安装xlsx库:
npm install xlsx # 或者用yarn yarn add xlsx
步骤2:修改你的上传处理逻辑
你不需要再依赖base64转码了,直接通过FileReader读取文件的二进制数据,再用xlsx解析即可。结合你现有的react-file-reader组件,修改后的代码如下:
import XLSX from 'xlsx'; // 处理文件上传的方法 onFileUpload = (files) => { // 因为设置了multipleFiles={false},所以取第一个文件 const targetFile = files[0]; const reader = new FileReader(); reader.onload = (e) => { // 将读取到的文件数据转换成Uint8Array格式 const fileData = new Uint8Array(e.target.result); // 解析Excel文件 const workbook = XLSX.read(fileData, { type: 'array' }); // 获取第一个工作表的名称(Excel可能有多个sheet) const firstSheetName = workbook.SheetNames[0]; // 获取对应的工作表内容 const worksheet = workbook.Sheets[firstSheetName]; // 将工作表转换成CSV格式(和你之前处理.csv的输出格式一致) const csvOutput = XLSX.utils.sheet_to_csv(worksheet); console.log('解析后的CSV数据:', csvOutput); // 如果你需要JSON格式,也可以这样转换: // const jsonOutput = XLSX.utils.sheet_to_json(worksheet); // console.log('解析后的JSON数据:', jsonOutput); }; // 以ArrayBuffer格式读取文件 reader.readAsArrayBuffer(targetFile); };
然后修改ReactFileReader的属性,去掉base64={true}(因为我们不需要转base64了):
<ReactFileReader fileTypes={[".csv", ".xls", ".xlsx"]} multipleFiles={false} handleFiles={this.onFileUpload} > <button className='btn'>Upload</button> </ReactFileReader>
如果你坚持想用base64处理
如果因为某些原因必须用base64格式的文件数据,也可以把base64转成二进制数组后再解析:
onFileUpload(file) { // 将base64字符串解码成二进制 const binaryStr = atob(file.base64); const data = new Uint8Array(binaryStr.length); for (let i = 0; i < binaryStr.length; i++) { data[i] = binaryStr.charCodeAt(i); } // 后续解析逻辑和上面一致 const workbook = XLSX.read(data, { type: 'array' }); const firstSheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[firstSheetName]; const csvOutput = XLSX.utils.sheet_to_csv(worksheet); console.log(csvOutput); }
不过这种方式多了一次转码,效率不如直接读取ArrayBuffer,更推荐前面的方案。
内容的提问来源于stack exchange,提问作者Valip
相关产品推荐
相关产品推荐

