導入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 },