使用React SheetJs读取多个Excel文件失效问题求助
故障根因
你的代码存在3处核心问题导致无法读取多文件:
- 拖拽逻辑仅处理第一个文件:
DragDropFile组件的onDrop方法仅传递了files[0]给父组件,其余选中文件被直接丢弃 - 单文件处理逻辑直接覆盖状态:原
handleFile每次解析完成后直接赋值state.data,后解析的文件会覆盖之前的解析结果 - 缺失input多文件适配:你贴出的input代码未添加
multiple属性,且对应的handleChange方法大概率也仅处理了首个选中文件
分步修改方案
1. 调整State结构适配多文件存储
修改组件初始化的state,用数组存储所有文件的解析结果:
// 组件constructor内的state初始化调整为 this.state = { fileList: [], // 每个元素存储单个文件的解析数据:包含fileName、data、cols三个字段 // 其余原有state属性保留 }
2. 改造DragDropFile组件传递全量文件
修改onDrop方法,将所有拖拽选中的文件传递给父组件:
onDrop(evt) { evt.stopPropagation() evt.preventDefault() const files = evt.dataTransfer.files if (files && files.length) { this.props.handleFiles(files) } }
3. 新增批量文件解析逻辑
将单文件解析包装为Promise,支持批量并行处理多个文件,避免异步解析导致的状态覆盖问题:
// 单个Excel文件解析逻辑 parseSingleFile(file) { return new Promise((resolve, reject) => { const reader = new FileReader() const rABS = !!reader.readAsBinaryString reader.onload = e => { try { const bstr = e.target.result const wb = XLSX.read(bstr, { type: rABS ? "binary" : "array" }) const wsname = wb.SheetNames[0] const ws = wb.Sheets[wsname] const data = XLSX.utils.sheet_to_json(ws, { header: 1 }) const cols = make_cols(ws["!ref"]) resolve({ fileName: file.name, data, cols }) } catch (err) { reject(err) } } reader.onerror = reject if (rABS) reader.readAsBinaryString(file) else reader.readAsArrayBuffer(file) }) } // 批量处理选中的所有文件 async handleFiles(files) { // 并行解析所有文件 const parsedFiles = await Promise.all( Array.from(files).map(file => this.parseSingleFile(file)) ) // 解析完成后统一更新状态,此处如果需要覆盖历史文件直接赋值fileList: parsedFiles即可 this.setState(prev => ({ fileList: [...prev.fileList, ...parsedFiles] })) }
4. 适配input多文件选择
首先给input标签添加multiple属性,同时补全对应的handleChange方法:
<input type="file" className="form-control" id="file" accept={SheetJSFT} multiple // 新增多文件选择支持 onChange={this.handleChange} />
// input选中文件的回调方法 handleChange(e) { const files = e.target.files if (files && files.length) { this.handleFiles(files) } }
5. 修改渲染逻辑适配多文件展示
遍历state.fileList渲染所有解析后的文件内容:
{this.state.fileList.map((fileItem, index) => ( <SingleFile key={index} fileData={fileItem} /> ))}
内容的提问来源于stack exchange,提问作者SalmaneOuarab
相关产品推荐
相关产品推荐

