vue+springboot+axios实现上传和下载功能

使用vue+element-ui+axios+springboot实现文件的上传和下载功能。点击"文件上传"按钮,弹出一个文件上传的弹框,然后在里面操作文件上传。点击"下载",就下载文件,后端将文件转为二进制流传到前端,然后前端使用js-file-download库来接收实现下载。

一、封装axios

先封装一个axios实例,方便以后调用,要用到里面的网络请求方法时,导入就行了。

import axios from 'axios'
function request(config){
  // 创建axios的实例
  const instance = axios.create({
    baseURL: 'http://localhost:8081', // 这个是后端的ip地址
  });
  return instance(config);
}
export function uploadResult(){ // 上传文件的方法
  return axios.create({
    withCredentials: true,
  });
}
export function getResult(resultfile){
  return request({
    url: 'comp/getCompResult',
    method: 'post',
    responseType: 'arraybuffer',
    data: {
      resultfile
    }
  });
}

二、上传功能的实现

1. 前端部分

前端上传功能使用element-ui的upload模块来实现上传功能,这里不需要upload默认的上传功能,因此要重写一下上传的函数。为了后端处理方便,前端就限制只能上传一个文件。

el-dialog

visible.sync用来显示和隐藏对话框,它是一个boolean类型,设置为true就是显示对话框,false就是隐藏对话框。因此,实现显示和隐藏对话框功能,只需要控制visible.synctruefalse就行了。

close是对话框关闭的回调,如果用户什么都没做,没有点击上传就关闭对话框的话,应该清空选取的文件。

el-upload

fileList是用来存储的选取的文件列表,其类型是数组。

auto-upload是设置是否在选取文件后立即上传,false则表示选取文件后不上传。

http-request用来覆盖默认的上传行为,可以自定义上传文件的实现,uploadHttpRequest是自己自定义的上传文件的方法。

on-change是文件状态改变时的函数钩子,添加文件、上传成功和上传失败时都会被调用,它默认会传入filefileList两个参数,前者是当前所操作的文件,后者是文件列表。

action设置为#,因为我们要重写上传方法,在上传方法里再写接收文件的后端接口地址。

<el-dialog width="400px" top="8vh" title="上传比赛结果" @close="closeUpload" :visible.sync="upload_visible">
          <el-upload :file-list="fileList"
                     :auto-upload="false"
                     :http-request="uploadHttpRequest"
                     class="upload-demo"
                     :on-change="fileChange"
                     ref="upload"
                     drag
                     action="#">
            <i class="el-icon-upload"/>
            <div class="el-upload__text">将文件拖到此处,或<em>点击选取文件</em></div>
            <div slot="tip" class="el-upload__tip">一次只能上传一个文件</div>
          </el-upload>
          <el-button type="success" @click="submitUpload" style="margin-left: 30px; margin-top: 20px">上传</el-button>
</el-dialog>

上传的样式应该是这样子的:

在这里插入图片描述

data

data里面,添加fileList来存取选取的文件,使用数组来存取。(使用数组来存取可以方便以后选取多个文件时的存取情况)。

data(){
   return{
      fileList: [],
      upload_visible: false // 对话框默认不显示。需要上传时,点击按钮让该值改为true就能显示。
   }
},
method
fileChange(file, fileList) {
    // 因为是限制为只能上传一个文件,所以前端选取文件时,如果选取第二个文件时,要把第一个文件给覆盖掉。
    this.fileList = [fileList[fileList.length - 1]];
    // 也可以这样写:
    // this.fileList = [file]; 
},
closeUpload(){
    // 当对话框关闭时,清空已上传的文件列表,同时fileList重新设置为空数组
	this.$refs.upload.clearFiles(); // 这个是el-upload自带的清空文件列表方法
	this.fileList = [];
},
uploadHttpRequest(){
    // 检验用户是否未选取文件就上传
	if(this.fileList.length === 0){
        this.$message.warning('请添加文件');
        return
    }
    const formData = new FormData();
    formData.append('file', this.fileList[0].raw); // 要上传的文件
    // ${server.url}/comp/uploadResult 这个是后端接收的接口
    // withCredentials: true一定要设置,否则可能会上传不成功,这是个坑
    uploadResult().post(`${server.url}/comp/uploadResult`, formData).then(res =>{
        let {status, msg, data} = res.data;
        if(status === 200){
          this.$message.success('上传成功');
          this.fileList = []; // 上传成功就初始化文件列表
          this.upload_visible = false; // 然后关闭对话框
        }else{
          this.$message.error(msg); // 上传失败就输出失败信息
        }
      }).catch(err =>{
        this.$message.error(err);
    });
}// 自定义上传功能
submitUpload(){
	this.$refs.upload.submit(); // 这个会触发upload的http-request,手动上传文件
},
2. 后端部分

JSONResult是我自定义的JSON格式类,用来将后端数据以JSON的格式返回给前端接收。

@RequestMapping("/uploadResult")
public JSONResult upload(@RequestParam("file") MultipartFile file){
      String fileName = file.getOriginalFilename(); // 获取文件名
      File dest = new File(fileName);
      try{
          file.transferTo(dest);
      }catch(Exception e){
          return JSONResult.errorMsg(e.toString()); // 上传失败就返回前端上传失败的信息
      }
      return JSONResult.ok(); // 上传成功就返回前端上传成功的信息。
}

三、下载功能的实现

下载功能就容易实现了,后端获取文件,然后将文件用二进制流的形式传递给前端接收,前端接收到二进制流后,就用js-file-download来下载。

1. 下载和导入js-file-download

在vue项目所在的文件目录终端运行:

npm install js-file-download --save

然后导入:

import fileDownload from "js-file-download";
2. 前端部分
downloadResult(resultfile){
  getResult(resultfile).then(res =>{
    fileDownload(res.data, resultfile); // 使用js-file-download来接收二进制流然后下载
  }).catch(err =>{
    this.$message.error(err);
  });
},
3. 后端部分
@PostMapping("getResult")
public void getCompResult(@RequestBody Map<String, String> map, HttpServletResponse response) throws Exception {
    String path = "---"; // 这里的path是文件存储的路径
    InputStream inputStream = new FileInputStream(path);
    response.reset();
    response.setContentType("application/octet-stream");
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(map.get("resultfile"), "UTF-8"));
    ServletOutputStream outputStream = response.getOutputStream();
    byte[] b = new byte[1024];
    int len;
    while((len = inputStream.read(b)) > 0){
        outputStream.write(b, 0, len);
    }
    inputStream.close();
}
  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值