一、文件上传

文件包括了office、图片、文本文件等,数据库设计如下:

其中filePath为上传到服务器的路径

vuespringboot开发视频可以发文章 springboot vue文件上传下载_vue.js


前端:

<el-upload
          ref="upload"
          :headers="headers"
          :auto-upload="false"
          :on-success="fileUploadSuccess"
          :on-error="fileUploadError"
          :disabled="importBtnDisabled"
          :limit="3"
          :action="BASE_API+'/contract/file/uploads'"
          name="file"
          accept=".*">
          <el-button slot="trigger" size="mini" type="primary">选取文件</el-button>

            <el-button
            style="margin-left: 10px;"
            size="mini"
            type="success"
            @click="submitUpload">上传文件</el-button>
  
             <el-button
              icon="el-icon-delete"
              @click="handleDelete"
              type="danger"
              size="mini"
              >删除</el-button
            >
             </el-upload>

这里使用的是elementUI的上传组件,headers是设置该上传请求携带token操作,不然会报错500,在data中定义:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_vue.js_02


这里的getToken是request.js中定义的:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_vue.js_03


on-success和on-error是各种回调函数,根据需要设置,

action是提交地址,BASE_API同样需要在data中定义,process.env是使用config中的prod.env.js中的BASE_API

vuespringboot开发视频可以发文章 springboot vue文件上传下载_vue.js_04


vuespringboot开发视频可以发文章 springboot vue文件上传下载_上传_05


accept设置为".*"表明默认接收的文件类型,.doc、.pdf啥的,这里默认所有

前端到此就处理完了

后端:

controller层:首先地址对应的是前端中的action,

vuespringboot开发视频可以发文章 springboot vue文件上传下载_上传_06


传入的参数为MultipartFile 类型,首先定义了文件保存路径:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_上传_07


取配置文件值:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_spring boot_08


计划是按天数创建文件夹,9月20号上传的文件放在服务器的C:/xxxx/upload_file/2022-9-20文件夹下,然后把文件记录保存在文件表中:

@Override
    public boolean uploadFiles(MultipartFile file) {
        HashMap<String, String> message = new HashMap<>();
        if (!file.isEmpty()) {
            try {
                // 文件保存路径
                String today= DateUtil.today();
                String filePath = filepath + "/" +today+"/"+ file.getOriginalFilename();

                if (!new File(filePath).exists()){
                    new File(filePath).mkdirs();
                }
                // 转存文件
                file.transferTo(new File(filePath));
                message.put("status", filePath);

                Files files=new Files();
                User user = userService.getCurrentUser();
                files.setUploadMan(user.getNickname());
                files.setFileName(file.getOriginalFilename());
                files.setFilePath(filepath+today);
                files.setUploadTime(new Date());

                this.save(files);

            } catch (Exception e) {
//                e.printStackTrace();
                message.put("status", "error");
            }
        }
        return true;
    }

选取文件,上传:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_API_09

vuespringboot开发视频可以发文章 springboot vue文件上传下载_上传_10


成功上传到硬盘目录:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_spring boot_11

二:文件下载

前端:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_API_12


下载按钮绑定下载事件,传入当前选中文件的id和文件名:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_API_13


定义方法:

downFile(id,fileName){
        downloadFile(id).then((res=>{
        console.log(res);
				const data = res;
				let url = window.URL.createObjectURL(new Blob([data]));
				let link = document.createElement('a');
				link.style.display = 'none';
				link.href = url;
				link.setAttribute('download', fileName);
				document.body.appendChild(link);
				link.click();
        }));
    }

定义downloadFile并引入,注意返回值responseType: ‘blob’

export function downloadFile(id) {
    return request({
      url: '/contract/file/downloads?id='+id,
      method: 'post',
      responseType: 'blob'
    })
  }

需要注意的是,这个用的是vue的模板这里需要改动:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_java_14


后台接口返回值为void,这里拦截器拦截,没有res.code,会直接报错如下图,不会下载,这里我把它改成,等于500才报错,成功避免

vuespringboot开发视频可以发文章 springboot vue文件上传下载_java_15

后端:

controller:需要注意的是,这里返回值最好定义为void

vuespringboot开发视频可以发文章 springboot vue文件上传下载_vue.js_16

service:首先通过文件id,查询文件表,获得文件所在服务器的路径、文件名,拼接URI为filePath,传入File,得到文件对象,设置类型为application/octet-stream

public void downloadFiles2(String fileId, HttpServletResponse response) throws Exception {

        Files files = this.getById(fileId);
        String path = files.getFilePath();
        String fileName = files.getFileName();
        String filePath=path+"/"+fileName;
        File file=new File(filePath);
        
        response.reset();
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        response.setHeader(
                "Content-disposition",
                "attachment; filename="+fileName);
        try(
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                // 输出流
                BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        ){
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) > 0) {
                bos.write(buff, 0, len);
            }
        }
    }

测试,成功弹出下载页面:

vuespringboot开发视频可以发文章 springboot vue文件上传下载_vue.js_17