<el-uploadclass="uploadDemo":limit="1"dragaccept=".xls,.xlsx" <!-- 只保留Excel格式 -->:on-exceed="handleExceedFileLimit":on-change="handleChangeExcelFile":on-remove="handleRemoveExcelFile":before-remove="beforeRemoveFile":file-list="uploadExcelFileList":auto-upload="false"action=""
><i class="el-icon-upload"></i><center><div class="el-upload__text">將文件拖到此處,或<em>點擊上傳文件</em></div><div slot="tip" class="el-upload__tip">支持上傳EXCEL文件(.xls,.xlsx)<br />一次只允許上傳一個文件且文件大小不超過{{ maxFileSize }}MB)</div></center>
</el-upload>
<div><el-buttontype="primary"v-show="uploadExcelFileList.length > 0"@click="confirmExcelUpload">上傳</el-button>
</div>
(1)限制只能上傳 Excel 類型文件
修改accept屬性的值(accept=".pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx"
),只保留 Excel 相關的文件格式。
同時,在handleChangeExcelFile
方法中添加類型驗證(以 Vue 為例):
methods: {handleChangeExcelFile(file, fileList) {// 獲取文件后綴名const fileName = file.name;const suffix = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();// 驗證文件類型if (suffix !== '.xls' && suffix !== '.xlsx') {this.$message.error('請上傳Excel格式的文件(.xls或.xlsx)');// 從文件列表中移除不符合要求的文件this.uploadExcelFileList = fileList.filter(item => item.uid !== file.uid);return false;}// 后續的處理邏輯...}
}
①accept屬性在文件選擇對話框層面就過濾掉非 Excel 文件;
②代碼中的二次驗證可以防止用戶通過修改文件后綴名繞過限制;
(2)el-upload組件屬性
- :
on-exceed="handleExceedFileLimit"
作用:當上傳的文件數量超過 limit 限制時觸發的回調函數。
場景:例如設置了 :limit=“1”(最多傳 1 個文件),當用戶嘗試上傳第 2 個文件時觸發。
參數:接收兩個參數files
(超出的文件列表)和fileList
(當前所有文件列表)。
/*** 圖片超出個數限制*/
handleExceedFileLimit() {this.$message.error('已超出最大文件個數');
},
- :
on-change="handleChangeExcelFile"
作用:文件狀態發生變化時觸發(包括文件選擇、上傳成功 / 失敗、進度更新等)。
場景:選擇文件后、文件上傳中、上傳完成(成功 / 失敗)等時機都會觸發。
參數:接收三個參數 file(當前操作的文件對象)、fileList(當前所有文件列表)、event(原生事件)。
典型用途:
①驗證文件類型 / 大小
②更新上傳進度顯示
③處理上傳成功 / 失敗的邏輯
/*** 文件狀態發生改變時觸發*/
handleChangeExcelFile(file, fileList) {// 獲取文件后綴名const fileName = file.name;const suffix = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();// 驗證文件類型if (suffix !== '.xls' && suffix !== '.xlsx') {this.$message.error('請上傳Excel格式的文件(.xls或.xlsx)');// 從文件列表中移除不符合要求的文件this.uploadExcelFileList = fileList.filter(item => item.uid !== file.uid);return false;}// 添加文件this.uploadExcelFileList.push(file);
},
- :
on-remove="handleRemoveExcelFile"
作用:文件被成功刪除后觸發的回調函數。
場景:用戶刪除已選中 / 上傳的文件,且通過了 before-remove 驗證后觸發。
參數:接收兩個參數 file(被刪除的文件對象)和 fileList(刪除后的文件列表)。
典型用途:
①同步更新本地文件列表數據
②向后端發送刪除文件的請求(如果文件已上傳)
/*** 刪除文件*/
handleRemoveExcelFile(file, fileList) {this.uploadExcelFileList = [];
},
:before-remove="beforeRemoveFile"
作用:刪除文件前觸發的回調函數,用于確認是否允許刪除。
場景:用戶點擊刪除按鈕時,先執行此方法,再決定是否執行刪除操作。
參數:接收兩個參數 file(要刪除的文件對象)和 fileList(當前所有文件列表)。
特殊說明:
①返回 true 或 Promise resolve 時,允許刪除
②返回 false 或 Promise reject 時,阻止刪除
/*** 刪除文件之前的鉤子,參數為上傳的文件和文件列表,* 若返回 false 或者返回 Promise 且被 reject,則停止刪除。* @param file 移除的圖片* @param fileList 圖片列表*/
beforeRemoveFile(file, fileList) {return this.$confirm(`確定移除 ${file.name}?`);
},
(3)FormData 對象構建表單數據
FormData
對象,用于構建表單數據,專門用于在客戶端(瀏覽器)向服務器發送文件、鍵值對等數據,尤其適合文件上傳場景。
①數據容器:FormData
就像一個 “虛擬表單”,可以通過 append()
方法添加各種數據(字符串、數字、文件等)。
②適配文件上傳:由于要上傳 Excel 文件(二進制數據),普通的 JSON
格式無法處理二進制數據,而 FormData
是瀏覽器原生支持的、專門用于傳輸二進制數據(如文件)
和鍵值對
的格式,能完美適配文件上傳場景。
③與請求配合:通過 this.$request.post(url, formData)
發送請求時,瀏覽器會自動設置正確的請求頭(Content-Type: multipart/form-data
),確保服務器能正確解析表單數據(包括文件)。
/*** 文件上傳*/
confirmExcelUpload(){this.$confirm('確認上傳', '提示', {confirmButtonText: '確定',cancelButtonText: '取消',type: 'info'}).then(() => {const loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})if(this.yourId!='' && this.myId!=''){if(this.excelTemplateFileData.length > 0){this.$jitsoseVue.MessageWarning('只能上傳一個文件')loading.close()}else{let formData = new FormData() //文件表單對象// 檢查上傳的文件大小是否超過限制if (this.uploadExcelFileList[0].size > this.maxFileSize * 1024 * 1024) {this.uploadExcelFileList = []this.$jitsoseVue.MessageWarning('文件過大,請重新上傳')return}formData.append('yourId', this.yourId)formData.append('myId', this.myId)formData.append('file', this.uploadExcelFileList[0].raw)this.loading = true;let url = 'file/insertExcelFile'this.$request.post(url, formData).then(res => {this.$message({type: 'info',message: res.data.obj})this.uploadExcelFileList = []this.getExcelTemplateFile()loading.close()this.loading = false;})}}else{this.$jitsoseVue.MessageWarning('請選擇yourId與myId')loading.close()}}).catch(error => {this.$message({type: 'info',message: '已取消上傳'})})
},
服務器端接收后,可以通過這些鍵(yourId、myId、file)獲取對應的數據,從而完成文件上傳和業務處理。
簡單說,formData
在這里就是一個 “數據包”,打包了上傳文件和相關業務參數,方便通過 HTTP 請求發送給服務器。
(4)el-upload 組件的文件對象結構
在 Element UI 的 el-upload
組件中,this.uploadExcelFileList[0].raw
中的 .raw
是獲取原始文件對象的關鍵屬性,這與組件對文件的處理機制有關:
- el-upload 組件的文件對象結構
當用戶選擇文件后,el-upload會將文件信息封裝成一個組件自定義的文件對象,存入 file-list
綁定的數組(即 uploadExcelFileList
)中。這個對象包含兩類信息:
組件自定義的元數據:如 name
(文件名)、size
(文件大小)、uid
(唯一標識)、status
(上傳狀態)等。
瀏覽器原生的文件對象:通過 raw
屬性暴露,對應 HTML5 中的 File`對象(繼承自 Blob)。
- raw原因
原生 File 對象的必要性:
當需要通過 FormData 上傳文件、或在前端處理文件內容(如讀取 Excel 數據)時,必須使用瀏覽器原生的 File 對象。因為組件自定義的文件對象只是對文件信息的描述,而非實際可傳輸 / 可處理的文件數據。
FormData上傳的要求:
formData.append('file', 文件對象)
方法要求傳入的必須是原生 File
或 Blob
對象,才能正確構建包含文件二進制數據的表單數據。如果直接傳入組件的自定義文件對象(而非 .raw),會導致文件數據無法被正確識別和上傳。
- 舉例說明
如果打印 this.uploadExcelFileList[0],會看到類似結構:
{name: "數據表格.xlsx", // 組件提取的文件名size: 20480, // 組件計算的文件大小(字節)uid: "1629234567890", // 組件生成的唯一標識status: "ready", // 組件標記的狀態raw: File { // 原生File對象(關鍵!)name: "數據表格.xlsx",lastModified: 1629234567890,size: 20480,type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}
}
這里的 raw 才是實際可用于上傳的文件數據載體。