ElementUI 上传文件以及限制

发布时间:2021-02-23 09:17:22编辑:admin阅读(3713)

    一、概述

    现有项目中,涉及文件上传。要求:

    1. 文件必须是excel

    2. 只能上传1个文件

    3. 文件大小不能超过5M 

     

    二、Upload 上传

    注意:ElementUI Upload 上传,需要和后端api结合才能使用。

    演示环境使用django,版本为:3.1.5

     

    新建django项目

    新建django项目,项目名为upload_demo,app名为api

    1.png

     安装以下模块

    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测试页,效果如下:

    1.png

     

    上传非excel文件,效果如下:

    1.png

     

    上传大于5M的excel文件,效果如下:

    1.png

     

    上传正确的excel文件,效果如下:

    1.png

     

    查看接口返回信息,效果如下:

    1.png

     

    查看django项目的upload目录,就可以看到上传的文件了。

    1.png

     


关键字