实现从excel表格导入数据到vue项目列表中的功能
1、安装依赖
npm install xlsx -S
2、封装导入表格数据解析处理的函数
在src文件下新建utils文件夹(此文件夹一般存放自己封装的公共的工具类函数),新建excel.js文件
文件截图.png
在excel.js中引入
import XLSX form 'xlsx
封装代码如下:
import XLSX from 'xlsx'
/**
*
* @param {File} file 文件
* @param {Object} codeObj 每个对象所包含的属性,属性名
* @return {Promise} 读取文件为异步的,调用例如excel(file.raw, obj).then(res => {console.log(res)}),res为最终得到的数组数据
*/
export default function (file, codeObj, needAll) {
return new Promise(resolve => {
var reader = new FileReader();
FileReader.prototype.readAsBinaryString = function (f) {
var binary = "";
var wb; //读取完成的数据
var outdata;
var reader = new FileReader();
reader.onload = function (e) {
var bytes = new Uint8Array(reader.result);
var length = bytes.byteLength;
for (var i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
wb = XLSX.read(binary, { type: 'binary', cellDates: true });
let opt = {
defval: '', // 设置默认值为null, 没设置的话,单元格为空的时候会缺少相应的key
}
// outdata就是你想要的东西 excel导入的数据
outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], opt);
// excel 数据再处理
let arr = []
outdata.map(v => {
let obj = {}
for (let key in codeObj) {
obj[key] = v[codeObj[key]] || '';
}
if (JSON.stringify(obj) !== '{}') {
arr.push(obj)
}
})
if(needAll) {
resolve({data: [...arr], dataAll: outdata})
}else {
resolve([...arr]);
}
}
reader.readAsArrayBuffer(f);
}
reader.readAsBinaryString(file)
})
}
3、在index.vue中引入excel.js
import excel from "@/utils/excel";
4、在index.vue中实现导入功能,代码如下:
<el-upload action :auto-upload="false" :show-file-list="false" accept=".xlsx,.xls" :on-change="uploadChange">
<el-button >导入</el-button>
</el-upload>
js代码如下:
data(){
return{
genderList: [
{ label: "男", value: 1 },
{ label: "女", value: 0 },
{ label: "保密", value: 2 },
]
}
},
uploadChange(file) {
// console.log(file)
// 新建对象,为excel表格表头匹配字段
let obj = {
id:"编号",
projectName: "入职项目",
positionName: "入职岗位",
name: "入职人姓名",
sex: "入职人性别",
mobile: "入职人电话",
idNumber: "入职人身份证",
applicantName: "招聘人姓名",
departmentName: "招聘部门",
higherLevel: "招聘经理",
};
// 调用封装好的方法处理excel文件数据
excel(file.raw, obj).then((res) => {
console.log(res)
// 根据实际需求处理数据
// 若要求导入数据中编号为必填,则没有必填的数据删除
for (let i = res.length - 1; i > -1 ; i--) {
if (res[i].id == '') {
res.splice(i, 1)
}
}
// 若res数组为空,则弹出提示语
if (!res.length) {
this.$message.warning("请检查导入文件,未检测到符合模板的数据!");
return;
}
// 处理数据,如sex:女,根据this.genderList数组中定义的 0代表女,1代表男,则处理成 sex:0
res.map((item) => {
item.sex = this.getValue(this.genderList, item.sex);
});
// 若要求导入数据中姓名或入职项目为必填,否则给与警告提示
for (let i = 0; i < res.length; i++) {
if (res[i].name == '' || res[i].projectName == ''){
this.$message.warning("第"+(i+1) +"姓名或入职项目为必填!");
return
}
}
// res中数据处理好后调用相应的导入接口
if (res) {
let params = {
operationId: this.userMessage.employeeId,
operationAll: 1,
entryInfoList: res,
};
importEntryConfirm({ data: params }).then((result) => {
if (result.code === 0) {
this.dataList();
this.$message.success(result.message);
} else {
this.$message.error(result.message);
}
});
}
});
},
// 根据label值找到value
getValue(obj, label) {
var res = obj.find((item) => item.label == label);
return res ? res.value : "";
},
5、效果图如下:
(1)页面导入按钮
导入按钮.png
(2)选择文件
选择文件.png
(3)选择的excel内容
选择的excel内容.png
(4)打印处理后的数据
处理后的数据.png