vue avue通过elementui 自定义导入按钮实现导入excel表格
导入Excel功能实现步骤:
1.首先通过elementUI组件自定义导入按钮:如下图
代码如下:用的是elementUI的上传组件
实例1:列表(html部分)不需要下面的导入点击事件
<el-upload style="display:inline-block;" :show-file-list="false" ref="upload" class="upload-demo" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" :on-change="handleChange"> <el-button class="el-icon-upload2" size="small" type="primary">导入</el-button> </el-upload>
实例2:左树右表(html部分)
备注:因为需要在文件弹窗打开前做一些判断,所以将按钮提出到el-upload外部加了点击事件,然后调用上传功能
<el-upload style="display:inline-block;" :show-file-list="false" ref="upload" class="upload-demo" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" :on-change="handleChange"> </el-upload> <el-button class="el-icon-upload2" size="small" @click="upLoadFile" type="primary">导入</el-button>
2.在vue的methods方法内定义
备注:因为我的项目是左树右表的形式,必须选择要导入数据的树节点所以做了判断,如果不需要在上传时做判断的可以直接参考前面的实例1列表版本的html
导入点击事件代码如下:
//导入点击事件 upLoadFile() { //在点击事件内处理自己在弹窗打开前要做的逻辑 if (!this.selectTreeData.id) { this.$message.warning('请选择需要导入数据的机构') //这里是提示文字 return } if (this.selectTreeData.deptCategory != 14) { this.$message.warning('导入数据的机构必须为单位') return } this.$refs['upload'].$refs['upload-inner'].handleClick()//调用elementUI的内部上传方法 },
//上传事件绑定的方法 handleChange(file, fileList) { this.improtNum++//因为我的框架原因这里会走两遍导入接口,所以在vue的data内定义了improtNum:0,通过这个变量做的判断,让第一遍请求不满足条件,解决数据会导入两遍的尴尬 if (this.improtNum > 1) { this.$Export.xlsx(file.raw).then((data) => { const self = this const list = data.results const dataList = this.transitionExcel(list)//在调导入接口前调用处理表头的方法 importData(dataList).then( () => { self.onLoad(self.page) self.$message({ type: 'success', message: '操作成功!', }) }, (error) => { window.console.log(error) } ) }) } },
处理列表表头方法如下:
备注:我的项目必须拿到需要导入的节点,所以里边有对象合并的一步,如果不需要和字段进去可以忽略
//导入Excel表头转换 transitionExcel(data) { //建立转换关系,label为表格表头,value为导入接口需要的请求字段,有多少个字段定义多少个对象 const self = this const importDataList = [ { label: '年份', value: 'yearMinute' }, { label: '机构数量', value: 'organizationNumber' }, { label: '柴油用量(万升)', value: 'diesel' }, { label: '天然气用量(万立方米)', value: 'gas' }, { label: '水(吨)', value: 'water' }, { label: '汽油用量(万升)', value: 'gasoline' }, { label: '原煤用量(吨)', value: 'coal' }, { label: '车流总数(辆)', value: 'trafficNumber' }, ] const newData = [] // 1..遍历导入的数组, // 2.判断拿到的表头是否与定义的label一致 data.forEach((object) => { let newItem = {} for (const key in object) { if (Object.hasOwnProperty.call(object, key)) { // key//属性名 // const valueData = object[key] //属性值 const arr = importDataList.filter((item) => { if (key == item.label) { return item } }) newItem[arr[0].value] = object[key]//newItem对象内的value值=属性值 // arr[0].value//importDataList数组内对象的value值 } } // 1.拿到机构id 父级id this.selectTreeData.id,,this.selectTreeData.parentId // 2.合并到导入的数据对象中 // 1.遍历得到导入数据的每一个对象,将获取到的机构id合并进去 //列表实例1不要对象合并这一步直接return处理好的对象newItem即可 const obj = Object.assign(newItem, { levelId: self.selectTreeData.id, parentId: self.selectTreeData.parentId, }) newData.push(obj) }) return newData },