upload 文件自动上传写法,前后端 下载流文件流

<el-upload
          v-model:file-list="fileList"
          :action="app.api+'/student/student/import'"
          :headers="{
       //   'Content-Type': 'multipart/form-data;boundary=----split-boundary', 此处切记不要加,否则会造成后端报错  Required request part 'file' is not present 
          'token':token
          }"
          name="file"//此处默认为file
          class="upload-demo"
          @on-success="handleSuccess"
          :on-error="handleAvatarSuccess"
          :limit="3"
          :on-progress="beforeAvatarUpload"
        >
<!--:auto-upload="false"-->
          <!--          :http-request="replaceRes"-->
          <span v-if="jinDu">
            <el-progress style="width: 245px; height: 19px" :text-inside="true" :stroke-width="20"
                         :percentage="percentage"/>
          </span>
          <span v-if="isUpload" style="color: #59c2c7;cursor:pointer;"
                @click="uploadChangeValue">导入学生学籍信息</span>
          <template #tip>
            <span style="color: #ff8282; margin-left: 20px">{{ importText }}</span>
          </template>
        </el-upload>
<script lang="ts" setup>

//此处后端穿了一个流给前端,所以需要解析一下,然后赋值给一个按钮,在点击时候才下载!!!
const handleSuccess = (response: any) => {
  console.log(response)
  if (Object.values(response.headers)[0] == 'application/vnd.ms-excel;charset=UTF-8') {
    const url = window.URL.createObjectURL(new Blob([response.data]));
    // 创建a标签,并隐藏a标签
    let link = document.createElement('a')
    link.style.display = 'none'
    // a标签的href属性指定下载链接
    link.href = url
    //setAttribute() 方法添加指定的属性,并为其赋指定的值
    // 后缀格式.csv/.xsls要和需要和后端返回格式相同,这里以.csv为例
    link.setAttribute('download', '文件名称.xlsx')
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }
};


//此处用于实时监听进度条进度
const beforeAvatarUpload = (event: any) => {
  let loadProgress = Math.floor(event.percent); //这就是当前上传的进度
  //可以进行其他逻辑
  percentage.value = loadProgress;
  importText.value = "学籍信息导入中……";
  if (percentage.value == 100) {
    importText.value = "学籍导入成功!"
  }
};
</script>
    @PostMapping("import")
    @ApiOperation("导入")
    @RequiresPermissions("student:student:import")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "file")
    public void importExcel(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws Exception {
        UserDetail userDetail = SecurityUser.getUser();
        //保存所有的表单信息、如果表达有错误、将返回给客户端
        if (userWithErrorListInMap == null) {
            userWithErrorListInMap = new HashMap<>();
        }
        //每次都清空数据
        userWithErrorListInMap.put(userDetail.getId(), new ArrayList<>());

        ZsRef<Boolean> hasError = new ZsRef<>();
        new ExcelServiceListener<StudentExcel, StudentEntity>(studentService, file.getInputStream()) {
            private List<RegionEntity> regionList;

            /**
             * 地区编码 去掉末尾的数字0, 用于判断权限
             */
            private String userRegionCodeForPermission;

            private SchoolEntity schoolForPermission;

            @Override
            public void invoke(StudentExcel data, AnalysisContext context) {

                if (regionList == null) {
                    regionList = regionService.selectList(new HashMap<>());
                }
                if (userDetail.getRegionCode() != null) {
                    //去掉地区编码后面的0
                    userRegionCodeForPermission = userDetail.getRegionCode().replaceAll("0+?$", "");
                }

                if (userDetail.getSchoolCode() != null) {
                    schoolForPermission = schoolService.selectByParams("schoolCode", userDetail.getSchoolCode());
                }
                // 校验姓名
                if (data.getName() == null) {
                    hasError.value = true;
                    data.setName(data.getName() + "##名字不能为空, 长度最多四汉字");
                }
                // 校验性别
                if (data.getGender() == 2) {
                    hasError.value = true;
                    data.setGenderStr(data.getGenderStr() + "##性别只能是(男、女)中的一个");
                }

                // 校验身份证号
                if (isEmpty(data.getIdCard()) || data.getIdCard().length() != 18) {
                    hasError.value = true;
                    data.setName(data.getName() + "##身份证长度18位");
                }

                if (isEmpty(data.getNation())) {
                    hasError.value = true;
                    data.setNation(data.getNation() + "##民族不能为空");
                }

                // ************************ 校验地区 *********************************
                // 判断地区表中是否包含含这一项
                RegionEntity region1 = null, region2 = null;
                for (RegionEntity item : regionList) {
                    if (data.getRegion1() != null && data.getRegion1().contains(item.getName())) {
                        region1 = item;
                    }
                    if (data.getRegion2() != null && data.getRegion2().contains(item.getName())) {
                        region2 = item;
                    }
                }
                // RegionEntity region = regionList.stream().filter(r -> r.getName().contains(data.getRegion())).findFirst().orElse(null);
                if (region1 == null) {
                    hasError.value = true;
                    data.setRegion1(data.getRegion1() + "##城市不存在");
                }

                if (region2 == null) {
                    if (data.getRegion1().contains("济源")) {
                        //济源没有区县
                    } else {
                        hasError.value = true;
                        data.setRegion2(data.getRegion2() + "##区县不存在");
                    }
                }

                if (region1 != null && region2 != null) {
                    data.setRegionCode(region2.getCode());
                    //判断地区和学校 是否具备权限
                    if (isNotEmpty(userDetail.getRegionCode())) {
                        if (String.valueOf(data.getRegionCode()).startsWith(userRegionCodeForPermission)) {
                            //具备权限
                        } else {
                            hasError.value = true;
                            data.setRegion2(data.getRegion2() + "##不具备该地区的权限");
                        }
                    }
                }

                //判断是否具备该学校的权限
                if (isNotEmpty(userDetail.getSchoolCode())) {
                    if (isEquals(schoolForPermission.getName(), data.getSchoolName())) {
                        //具备权限
                    } else {
                        hasError.value = true;
                        data.setSchoolName(data.getSchoolName() + "##不具备该学校的权限");
                    }
                } else {
                    //不需要判断学校权限
                }

                if (isEquals(hasError.value, true)) {
                    userWithErrorListInMap.get(userDetail.getId()).add(data);
                } else {
                    //没有错误的才添加
                    super.list.add(data);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                if (isEquals(hasError.value, true)) {
                    //  有错误, 不入库
                } else {
                    studentService.saveStudentWidthSchoolAndClass(super.list);
                }
            }
        }.start(2);

        if (Objects.equals(hasError.value, true)) {
            String errorFileName = file.getOriginalFilename().replace(".xlsx", "错误提示.xlsx");
            export(response, errorFileName, userWithErrorListInMap.get(userDetail.getId()));
        } else {
            PrintWriter pw = response.getWriter();
            //逻辑删除导入学籍时学籍不存在的学校班级(当前学期)
            schoolService.deleteBySchoolCode();
            gradeClassService.deleteByClassCode();
            //恢复导入学籍时学籍存在但逻辑删除的学校班级(当前学期)
            schoolService.updateBySchoolCode();
            gradeClassService.updateByClassCode();
            pw.write(ZsJson.toJson(new Result<>()));
            pw.close();
        }
        System.out.println("excel解析完成");
    }

下载一个后端返回的流文件

注意跨域问题

后端解决跨域问题

const downLoadExport=()=>{
  axios({
    method: 'post',
    url: baseUrl+"/electric/electricassets/download/assets",
    headers: {
      "Content-Type": "application/json;charset=UTF-8",
      "token":getToken()
    },
    responseType: 'blob'
  }).then(response => {
    if (Object.values(response.headers)[0]=='application/vnd.ms-excel;charset=UTF-8'){
      const url = window.URL.createObjectURL(new Blob([response.data]));
      // 创建a标签,并隐藏a标签
      let link = document.createElement('a')
      link.style.display = 'none'
      // a标签的href属性指定下载链接
      link.href = url
      //setAttribute() 方法添加指定的属性,并为其赋指定的值
      // 后缀格式.csv/.xsls要和需要和后端返回格式相同,这里以.csv为例
      link.setAttribute('download',   '文件名称.xlsx')
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    }
  })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 前端页面代码(HTML): ```html <form action="/upload" method="POST" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="上传"> </form> ``` 后端代码(Flask): ```python from flask import Flask, request app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload(): file = request.files['file'] file.save('path/to/save/file') return '文件上传成功' ``` 注意: 上传文件保存的路径需要是绝对路径。 ### 回答2: Flask是一个轻量级的Python Web开发框架,提供了简单而灵活的方式来处理文件上传文件上传涉及到前后端两个方面的代码编写,下面是关于Flask文件上传前后端写法。 前端写法: 1. 在HTML表单中添加一个文件上传输入框,并设置相应的name属性以便后端处理。 `<input type="file" name="file">` 2. 使用JavaScript监听文件上传输入框的change事件,获取选中的文件对象。 ``` const fileInput = document.querySelector('input[type="file"]'); fileInput.addEventListener('change', (event) => { const file = event.target.files[0]; // 处理文件... }); ``` 3. 将选中的文件对象以FormData的形式发送到后端。 ``` const fileInput = document.querySelector('input[type="file"]'); const formData = new FormData(); formData.append('file', fileInput.files[0]); // 发送FormData到后端... ``` 后端写法: 1. 在Flask中导入相关模块。 ``` from flask import Flask, request from werkzeug.utils import secure_filename ``` 2. 创建Flask应用。 ``` app = Flask(__name__) ``` 3. 设置文件上传的保存路径。 ``` app.config['UPLOAD_FOLDER'] = '/path/to/uploads' ``` 4. 定义文件上传的路由。 ``` @app.route('/upload', methods=['POST']) def upload_file(): file = request.files['file'] if file: filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # 文件上传成功的处理逻辑... else: # 文件上传失败的处理逻辑... ``` 上述代码中的`/path/to/uploads`是文件保存的路径,可以根据需要进行修改。在后端文件上传路由中,首先从请求中获取文件对象,然后使用`secure_filename()`函数确保文件名的安全性,并将文件保存到指定的路径中。最后,根据文件上传的成功或失败情况处理相应的逻辑。 需要注意的是,Flask默认的文件上传大小限制为16MB。如果需要上传更大的文件,可以通过配置`MAX_CONTENT_LENGTH`来修改。另外,还可以添加文件类型、大小等验证逻辑以增加安全性。 ### 回答3: Flask是一个轻量级的Python Web框架,用于构建Web应用程序。关于Flask上传文件前后端写法,涵盖了前端页面展示和后端处理两部分。 前端页面展示: 1. 在HTML页面中,需要添加一个表单元素用于文件上传,如<form>标签,并设置enctype属性为"multipart/form-data"。 2. 在表单中添加一个<input>标签,并设置type属性为"file",用于用户选择要上传文件。 3. 将表单元素和输入框包含在一个适当的位置,比如一个div元素中,以便于布局和样式设置。 后端处理: 1. 在Flask的应用程序中,需要引入"request"模块,该模块用于处理上传文件。 2. 使用@app.route装饰器定义一个路由,指定接收上传文件的URL地址,并设置方法为POST。 3. 在对应的视图函数中获取上传文件,通过request.files.get("file")即可获取到上传文件对象。 4. 通过文件对象的save()方法,将文件保存到服务器上的指定位置。可以为每个上传文件设置一个保存路径,比如app.config['UPLOAD_FOLDER']。 5. 针对上传文件的需求,可以进行文件格式、大小、后缀等验证和处理,如通过文件对象的filename属性获取文件的名称和后缀,通过文件对象的content_type属性获取文件的MIME类型等。 以上是Flask上传文件的简要介绍,具体的实现细节和业务逻辑根据具体需求和应用场景的不同可能会有所差异。这只是一个简单的示例,可以根据实际情况进行扩展和定制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值