1.在编写代码之前我们先来认识一些FileReader()读取文件
FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
其中File对象可以是来自用户在一个元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。
常用事件
FileReader.onload事件在读取完成后触发。


<!-- 上传文件按钮 -->
<div class="buttonBox">
<el-upload
action
accept=".xlsx, .xls"
:auto-upload="false"
:show-file-list="false"
:on-change="handle"
>
<el-button type="primary" slot="trigger">选取EXCEL文件</el-button>
</el-upload>
<el-button type="success" @click="submit" :disabled="disable"
>采集数据提交</el-button
>
</div>
Upload.vue文件
methods: {
// 采集EXCEL数据
async handle(ev) {
let file = ev.raw; //这边ev打印出是一个对象,可以看如下截图
if (!file) return;
this.show = false;
let loadingInstance = Loading.service({
text: "小主,请您稍等片刻,奴家正在玩命处理中!",
background: "rgba(0,0,0,.5)",
});
await delay(100);
//读取FILE中的数据(变为JSON格式)
let data = await readFile(file);
let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
console.log(workbook);
let worksheet = workbook.Sheets[workbook.SheetNames[0]]; //拿到sheet的数据
console.log(worksheet);
data = xlsx.utils.sheet_to_json(worksheet); //xlsx这个插件帮我们处理成json格式数据
console.log(data);
//把读取出来的数据变为最后可以传递给服务器的数据(姓名:name 电话:phone)
let arr = [];
data.forEach((item) => {
let obj = {};
for (let key in character) {
if (!character.hasOwnProperty(key)) break;
let v = character[key],
text = v.text,
type = v.type;
v = item[text] || "";
type === "string" ? (v = String(v)) : null;
type === "number" ? (v = Number(v)) : null;
obj[key] = v;
}
arr.push(obj);
});
await delay(100);
// 展示到页面中
this.show = true;
this.tempData = arr;
loadingInstance.close();
},
// 提交数据给服务器
async submit() {
if (this.tempData.length <= 0) {
this.$message({
message: "小主,请您先选择EXCEL文件!",
type: "warning",
showClose: true,
});
return;
}
this.disable = true;
let loadingInstance = Loading.service({
text: "小主,请您稍等片刻,奴家正在玩命处理中!",
background: "rgba(0,0,0,.5)",
});
// 完成后处理的事情
let complate = () => {
this.$message({
message: "小主,奴家已经帮您把数据上传了!",
type: "success",
showClose: true,
});
this.show = false;
this.disable = false;
loadingInstance.close();
};
// 需要把数据一条条传递给服务器
let n = 0;
let send = async () => {
if (n > this.tempData.length - 1) {
// 都传递完了
complate();
return;
}
let body = this.tempData[n];
let result = await createAPI(body);
if (parseInt(result.code) === 0) {
// 成功
n++;
}
send();
};
send();
},
},

2.然后我们读取该file,我们通过FileReader把该file读取为二进制编码。
Upload.vue
//读取FILE中的数据(变为JSON格式)
let data = await readFile(file);
let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
console.log(workbook);
let worksheet = workbook.Sheets[workbook.SheetNames[0]]; //拿到sheet的数据
console.log(worksheet);
data = xlsx.utils.sheet_to_json(worksheet); //xlsx这个插件帮我们处理成json格式数据
console.log(data);
我们在utils.js文件封装一个读取为二进制编码的方法,如下ev.target.result打印出是一个二进制的数据。

FileReader 包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。
image.png
文件一旦开始读取,无论成功或失败,实例的 result 属性都会被填充。如果读取失败,则 result 的值为 null ,否则即是读取的结果,绝大多数的程序都会在成功读取文件的时候,抓取这个值。
3.通过刚才第二步骤我们知道了二进制数据,然后在将二进制数据用插件读取,读取之后生成一个excel的工作目录。
let data = await readFile(file);
let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
console.log(workbook);
打印出如下

4.我们通过这个workbook.Sheets[workbook.SheetNames[0]]拿到sheet的数据,然后我们需要转成json格式的数据如何操作?【我们是通过xlsx.utils.sheet_to_json(worksheet)】转成json格式数据。

let data = await readFile(file);
let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
console.log(workbook);
let worksheet = workbook.Sheets[workbook.SheetNames[0]]; //拿到sheet的数据
console.log(worksheet);
data = xlsx.utils.sheet_to_json(worksheet); //xlsx这个插件帮我们处理成json格式数据
console.log(data);
打印如下

6k条的数据解析差不多30s左右,如果是上传到服务器差不多要3分钟。
5.此时我们成功的转化为json数据,但是当我们调接口传给服务器肯定是不能以姓名和电话这个中文名这个字段传给服务器,所以我们需要转一下。注意:【这边拿到的电话是number类型,一般数字我们需要转成number在传给后端】
代码处理如下:
console.log(data);
//把读取出来的数据变为最后可以传递给服务器的数据(姓名:name 电话:phone)
let arr = [];
data.forEach((item) => { //这里的item指的是{name:"老王",电话:18856565656}
let obj = {};
for (let key in character) {
if (!character.hasOwnProperty(key)) break;
let v = character[key],
text = v.text,
type = v.type;
v = item[text] || "";
type === "string" ? (v = String(v)) : null;
type === "number" ? (v = Number(v)) : null;
obj[key] = v;
}
arr.push(obj);
});
console.log(arr)
utils.js文件代码

打印出来效果如下:

6.然后等表格全部读取之后才显示出来,我们现在data中定义一个show为false
image.png
image.png
每次解析数据之前,都把我们的表格隐藏掉,当我们拿到数据才显示。

7.这边做个loading的视觉效果
image.png
delay是在utils.js里面封装
image.png
8.完成以上步骤之后接下来就是调用接口,准备把数据上传到服务器上面,有两种上传方式,一种是数据同时发,另外一种是把数据一条一条发送,这边选用一条一条发送。
image.png
image.png
image.png
// 提交数据给服务器
async submit() {
if (this.tempData.length <= 0) {
this.$message({
message: "小主,请您先选择EXCEL文件!",
type: "warning",
showClose: true,
});
return;
}
this.disable = true;
let loadingInstance = Loading.service({
text: "小主,请您稍等片刻,奴家正在玩命处理中!",
background: "rgba(0,0,0,.5)",
});
// 完成后处理的事情
let complate = () => {
this.$message({
message: "小主,奴家已经帮您把数据上传了!",
type: "success",
showClose: true,
});
this.show = false;
this.disable = false;
loadingInstance.close();
};
// 需要把数据一条条传递给服务器
let n = 0;
let send = async () => {
if (n > this.tempData.length - 1) {
// 都传递完了
complate();
return;
}
let body = this.tempData[n];
let result = await createAPI(body);
if (parseInt(result.code) === 0) {
// 成功
n++;
}
send();
};
send();
},
},







