一、概述
現有項目中,涉及文件上傳。要求:
1. 文件必須是excel
2. 只能上傳1個文件
3. 文件大小不能超過5M
二、Upload 上傳
注意:ElementUI Upload 上傳,需要和后端api結合才能使用。
演示環境使用django,版本為:3.1.5
新建django項目
新建django項目,項目名為upload_demo,app名為api
安裝以下模塊
Django==3.1.5 djangorestframework==3.11.1 django-cors-headers==3.5.0
以上是我環境的版本,這里不做強制要求,安裝最新版本即可。
注意:django-cors-headers是用來解決跨域問題的。
修改upload_demo/settings.py
注冊app
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'api.apps.ApiConfig', 'rest_framework', 'corsheaders', # 注冊應用cors ]
中間件增加
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'corsheaders.middleware.CorsMiddleware', # 注冊組件cors ]
最后一行增加
#跨域增加忽略 CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_ALLOW_ALL = True # CORS_ORIGIN_WHITELIST = ( # 'http://', # ) CORS_ALLOW_METHODS = ( 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'VIEW', ) CORS_ALLOW_HEADERS = ( 'XMLHttpRequest', 'X_FILENAME', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', 'Pragma', )
修改api/views.py,增加視圖函數

from rest_framework.views import APIView from upload_demo import settings from django.shortcuts import render, redirect, HttpResponse from django.http import JsonResponse from rest_framework import status import os import uuid class File(APIView): def post(self, request): print(request.FILES) # 接收文件 file_obj = request.FILES.get('file', None) print("file_obj", file_obj.name) # 判斷是否存在文件夾 head_path = os.path.join(settings.BASE_DIR,'upload') print("head_path", head_path) # 如果沒有就創建文件路徑 if not os.path.exists(head_path): os.makedirs(head_path) # 判斷文件大小不能超過5M if file_obj.size > 5242880: return JsonResponse({'status': status.HTTP_403_FORBIDDEN, 'msg': '文件過大'}, status=status.HTTP_403_FORBIDDEN) # 文件后綴 suffix = file_obj.name.split(".").pop() print("文件后綴", suffix) # 圖片后綴 png # 判斷文件后綴 suffix_list = ["xlsx","xls"] if suffix not in suffix_list: return JsonResponse({'status': status.HTTP_403_FORBIDDEN, 'msg': '只能選擇excel文件'}, status=status.HTTP_403_FORBIDDEN) # 重命名文件名 file_name = '%s.%s'%(uuid.uuid4(),suffix) print("file_name",file_name) # 儲存路徑 file_path = os.path.join(head_path,file_name) print("儲存路徑", file_path) # 寫入文件到指定路徑 with open(file_path, 'wb') as f: for chunk in file_obj.chunks(): f.write(chunk) data = {} data['name'] = file_name return JsonResponse({'status': status.HTTP_200_OK, 'data': data}, status=status.HTTP_200_OK)
修改upload_demo/urls.py
from django.contrib import admin from django.urls import path from api import views urlpatterns = [ path('admin/', admin.site.urls), path('file/excel_upload/',views.File.as_view()) ]
啟動django項目,訪問鏈接為:http://127.0.0.1:8000/
新建vue測試頁
安裝axios
npm install axios --save
test.vue

<template> <div style="width: 70%;margin-left: 30px;margin-top: 30px;"> <el-upload ref="upload" class="upload-demo" :multiple='false' :auto-upload='true' list-type='text' :show-file-list='true' :before-upload="beforeUpload" :before-remove="beforeRemove" :drag='true' action='' :limit="1" :on-exceed="handleExceed" :http-request="uploadFile" accept=".xlsx" > <i class="el-icon-upload"></i> <div class="el-upload__text"><em>點擊上傳,僅限excel文件</em></div> <!-- <div class="el-upload__tip" slot="tip">僅限excel文件</div>--> </el-upload> <el-button type="primary" @click="onSubumit">提交</el-button> </div> </template> <script> // 導入模塊 import axios from 'axios' export default { components: { axios }, data() { return { isUpload:false, // 是否上傳文件 } }, mounted: function() { }, methods: { // 上傳文件之前的鈎子 beforeUpload(file) { //判斷文件格式 let hz = file.name.split('.').pop() // console.log("hz",hz) if (hz != 'xlsx' && hz != 'xls') { this.$message.error(`只能選擇excel文件`) return false } // 判斷文件大小 let fileSize = file.size / 1024 / 1024 < 5 if (!fileSize) { this.$message.error('上傳文件大小不能超過 5MB') return false } this.isUpload = true }, // 刪除文件之前的鈎子 beforeRemove(file){ this.isUpload = false }, // 上傳文件個數超過定義的數量 handleExceed(files, fileList) { this.$message.warning(`當前限制選擇 1 個文件,請刪除后繼續上傳`) }, // 上傳文件 uploadFile(item) { let _this = this let fileObj = item.file const form = new FormData()// FormData 對象 form.append('file', fileObj)// 文件對象 'upload'是后台接收的參數名 axios({ url: 'http://127.0.0.1:8000/file/excel_upload/', data: form, method: 'POST', contentType: 'multipart/form-data', processData: false //告訴jquery不要對form進行處理 // contentType: false, //指定為false才能形成正確的Content-Type }) .then(function(res) { // console.log('上傳成功', res) // console.log("上傳路徑",res.data.excel_file_path) _this.$message.success("上傳成功") }) .catch(function(err) { let res = err.response // console.log('失敗', res) _this.$message.error(res.data.msg) }) }, // 檢查是否上傳 onSubumit(){ if (this.isUpload == false){ this.$message.error("請上傳excel文件") return false } else { this.$message.success("文件已上傳") return true } }, } } </script> <style> </style>
請自行修改路由
訪問vue測試頁,效果如下:
上傳非excel文件,效果如下:
上傳大於5M的excel文件,效果如下:
上傳正確的excel文件,效果如下:
查看接口返回信息,效果如下:
查看django項目的upload目錄,就可以看到上傳的文件了。