咸吃萝卜淡操心:导入xlsx文件表格新增数据
0. 缘起
东西做着做着忽然发现表格下方有个(导入)按钮,我纳闷了,想之前就直接传了个文件,怕不是需要把tableData换成这个,于是就开始自己琢磨。最后捏,发现人后端做完了这个导入新增的功能,我默默地删了新写的代码,不过这玩意也挺有挑战的,值得纪念!
1. 代码
<el-upload
class="upload-demo"
name="excelFile"
:headers="getHeaders()"
:action="url"
:auto-upload="true"
:show-file-list="false"
:on-success="onSuccess"
:on-error="onError"
:before-upload="onBefore"
accept=".xlsx,.xls"
>
<el-button type="primary">导入</el-button>
</el-upload>
readExcel(file) {
console.log("file: ", file);
const fileReader = new FileReader();
fileReader.onload = (ev) => {
try {
const data = ev.target.result;
const workbook = XLSX.read(data, {
type: "binary",
});
for (let sheet in workbook.Sheets) {
const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
console.log("sheetArray: ", sheetArray);
}
} catch (e) {
this.$message.warning("文件类型不正确!");
return false;
}
};
fileReader.readAsBinaryString(file.raw);
},
// Update successfully
onSuccess(response, file) {
if (response.code === 0) {
this.$message.success({
message: "文件上传成功",
duration: 1000,
});
// this.readExcel(file);
} else {
this.$message.error(response.message);
}
this.loading.close();
},
2. 解析
其实大体上就两步,第一步,拿到XLSX,第二步,把XLSX里的file转换为可用的对象
2.1 解析XLSX的插件
npm install xlsx
import XLSX from 'xlsx'
2.2 获取file作为可用对象
这里我用了el-upload的上传文件成功的钩子来获取file,也可以用addEventListener的方法监听upload事件。注意这里参数列表第二个就是file,也是XLSX插件需要的。
参数 | 说明 | 类型 |
---|---|---|
on-success | 文件上传成功时的钩子 | function(response, file, fileList |
3. 导出 XLSX
exportExcel() {
let data = this.downloadData;
//
// 新建空workbook,然后加入worksheet
const ws = XLSX.utils.json_to_sheet(data);
// 设置每列的列宽,10代表10个字符,注意中文占2个字符
ws["!cols"] = [{ wch: 10 }, { wch: 25 }];
// 新建book
const wb = XLSX.utils.book_new();
// 生成xlsx文件(book,sheet数据,sheet命名)
XLSX.utils.book_append_sheet(wb, ws, "数据详情");
// 写文件(book,xlsx文件名称)
XLSX.writeFile(wb, this.sideTableTitle + "详情.xlsx");
},
for (let i = 0; i < sk.name.length; i++) {
self.downloadData.push({ 姓名: sk.name[i], 次数: sk.value[i] });
}
4. 实际运用
嘿嘿,没想到我还可以用这个来筛选表格数据,JS,恁太强大了!
4.1 从XLSX文件中获取数据
readExcel(file) {
console.log("file: ", file);
const fileReader = new FileReader();
fileReader.onload = (ev) => {
console.log("ev: ", ev);
try {
const data = ev.target.result;
const workbook = XLSX.read(data, { type: "binary" });
for (let sheet in workbook.Sheets) {
const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
console.log("sheetArray: ", sheetArray);
this.tableDataL = sheetArray.map((key) => {
return key?.nameL;
});
this.tableDataS = sheetArray
.map((key) => {
return key?.nameS;
})
.filter((key) => {
return key !== undefined;
});
console.log(this.tableDataS, "this.tableDataL: ", this.tableDataL);
this.getUniqueData();
}
} catch (e) {
this.$message.warning("文ERROR!");
console.log("ERROR IN READ");
return false;
}
};
fileReader.readAsBinaryString(file.raw);
},
4.2 数组处理
取两列数组中没有重复的值,交集取并
getUniqueData() {
let unique = this.tableDataL.filter((key) => {
return !this.tableDataS.includes(key);
});
console.log("unique", unique);
},
效果就是第一列70个名字,第二列100个名字,其中有70个是第一列的,要把不重复的30个找出来。
4.3 导出unique的XLSX文件
exportExcel() {
let data = this.getUniqueData().map((key) => {
return { name: key };
});
// self.downloadData.push({ 姓名: sk.name[i], 次数: sk.value[i] });
// 新建空workbook,然后加入worksheet
const ws = XLSX.utils.json_to_sheet(data);
// 设置每列的列宽,10代表10个字符,注意中文占2个字符
ws["!cols"] = [{ wch: 10 }, { wch: 25 }];
// 新建book
const wb = XLSX.utils.book_new();
// 生成xlsx文件(book,sheet数据,sheet命名)
XLSX.utils.book_append_sheet(wb, ws, "数据详情");
// 写文件(book,xlsx文件名称)
XLSX.writeFile(wb, "特殊姓名.xlsx");
},
引用
人生到处知何似,应似飞鸿踏雪泥。