需求:读取一个excel文件。
一、 使用antd的Upload组件的 【customRequest】方法。
- 互斥。此方法跟【onChange】方法互斥,即:不可同时出现。
- 调用次数不一样。onChange方法会根据文件当前的上传状态从而被调用多次(读取中,上传中,上传失败、上传完成等)。
customRequest方法是自定义读取和上传的文件,因此,onChange方法的几个状态,【customRequest】方法默认是没有的,因此【customRequest】方法只会被调用1次- 参数不一样。onChange方法在读取完成后,会拿到一个数据。这个数据是 antd组件处理过后的数据,包含了一些读取状态等其他属性。(但是也无法直接看到文件里的内容)。
【customRequest】方法拿到的file数据是未经处理的,无法看到文件里的数据。
二. 如何读取文件?
- readAsBinaryString 方法:按字节读取文件内容,结果为文件的二进制串。 这个结果,会作为参数 传递给 fileReader的 onload方法 (此方法会被逐渐废弃。不推荐使用。)
- readAsArrayBuffer 方法:同上,结果为ArrayBuffer (推荐使用)
数据转化过程:
- upload组件拿到的 原始的文件数据(customRequest的参数file)
- 二进制流 or ArrayBuffer 。readAsBinaryString的方式读取后的数据为二进制流。readAsArrayBuffer读取出来的数据是ArrayBuffer
- webhooks.里面是真个表的所有信息。
- sheet。某个子表单的数据。里面是每个单元格的信息
- sheet_to_json 方法将 sheet 转成 对象数组
import { read as xlsxRead, utils as xlsxUtils } from 'xlsx';// 批量导入const customRequest = (files) => {const { file } = files;// step1 :创建一个 fileReader对象const fileReader = new FileReader();// step2: onload方法是 读完数据后 调用的方法。用来对读取后的数据进行一些处理fileReader.onload = (event: any) => {try {const { result } = event.target;console.log('event', event);// 1 以二进制流方式(buffer方式)读取得到整份excel表格对象,cellDates设为true,将读取到的天数的时间戳转为时间格式const workbook = xlsxRead(result, {type: 'binary',//🐷🐷🐷 如果readAsArrayBuffer方法读取文件则type:'buffer'🐷🐷cellDates: true,});console.log('workbook', workbook);// 2 遍历每张工作表进行读取(这里默认只读取第一张表)Sheets是个数组const { Sheets } = workbook;const sheet0 = Sheets[Object.keys(Sheets)[0]];console.log('sheet0', sheet0);// 4 利用 sheet_to_json 方法将 sheet 转成 对象数组const fileData = xlsxUtils.sheet_to_json(sheet0)// convertToData(fileData);} catch (e) {// 这里可以抛出文件类型错误不正确的相关提示message.error(formatMessage({ id: 'create_order.fileError' }));}};
// step3: 使用 readAsBinaryString、或者 readAsArrayBuffer 来读取 文件。fileReader.readAsBinaryString(file);};
最后
二进制的数据流解析后。长什么样?
ArrayBuffer长什么样子?如下图。