前言

本次将使用vue和springboot通过文件流的方式教大家怎么去实现文件的下载,那么话不多说,我们直接开始

相关vue导出文件

以下链接为我其他vue进行下载导出文件文章
vue实现把字符串导出为txt

步骤

文件路径

要进行下载的话,我们肯定是需要一个路径进行获取到我们的文件的,那么本次我们的文件路径是这样:

D:\file\文件名称.pdf

ps: 文件名称.pdf是我进行上传的文件,D:\file\是我本地D盘下的磁盘路径
本次是在文件上传成功的基础上进行的
另外,如果希望知道怎么上传文件可以参考我的文章:
elementUI加springboot实现上传excel文件给后端并读取excel

vue前端代码

前端界面部分,比较简单,就是一个按钮,绑定一个click点击事件方法
本次我使用的框架为elementUI ,其他前端框架也是通用的,最主要是看逻辑部分
具体界面代码如下:

<template>
  <div>
  	<el-button size="medium" type="success" plain @click="downLoadFile">下载</el-button>
  </div>
</template>

最终按钮是这样
在这里插入图片描述
然后是JavaScript的逻辑部分
本次JavaScript逻辑有使用axios调用后端,具体如何使用和引入,参照百度

export default {
    name:"xxx",
    data(){
      return{
      filePath: 'D:\file\文件名称.pdf', // 文件路径
      fileName: '文件名称.pdf', // 文件名称
      }
    },
    methods:{
    	// 下载文件方法
    	downLoadFile() {
		    this.$axios.get("/downFile/downLoadFile",{
              params: {
                path: this.filePath,
                name: this.fileName
              },
              responseType: 'blob'
            }).then(res => {
              const blob = new Blob([res.data]);
              const fileName = res.headers["content-disposition"].split(";")[1].split("filename=")[1];
              if ('download' in document.createElement("a")) {
                const link = document.createElement("a");
                link.download = fileName;
                link.style.display = 'none';
                link.href = URL.createObjectURL(blob);
                document.body.appendChild(link);
                link.click();
                URL.revokeObjectURL(link.href);
                document.body.removeChild(link);
              } else {
                navigator.msSaveBlob(blob, fileName);
              }
			})
		}
    },
}

ps: 这边需要重点提一下,上面的代码
params: 需要传的参数,本次上传到的是路径和文件名称
responseType 我们申明一个blob的文件流的请求类型,让后端返回一个blob流文件,前端接收
res : 后端返回结果,可能被包了几层消息请求,根据实际的请求是决定是res.data或res.data.data或其他
res.headers["content-disposition"]:这里是由后端暴露一个请求头content-disposition,如果你能够直接知道文件名称,后端的暴露请求头步骤可以直接省略
document.createElement("a"): 通过创建一个< a>< /a>的标签,将文件流填入到a标签的url路径的方式把文件下载下来

后端代码

controller层
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/downFile")
public class DownFileController {
    @Resource
    private DownFileService downFileService;

	@GetMapping("/downLoadFile")
    @PassToken
    public ResultVO downLoadFile(@RequestParam("path") String path,@RequestParam("name") String name,HttpServletResponse response) throws Exception {
        return downFileService.downLoadFile(path,name,response);
    }
}
service层
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@Service
public class DownFileService {
	    public ResultVO downLoadFile(String path,String name,HttpServletResponse response) {
        File file = new File(path);
        byte[] buffer = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            //文件是否存在
            if (file.exists()) {
                //设置响应
                response.setContentType("application/octet-stream;charset=UTF-8");
                response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                response.setHeader("Content-Disposition","attachment;filename="+name);
                response.setCharacterEncoding("UTF-8");
                os = response.getOutputStream();
                bis = new BufferedInputStream(new FileInputStream(file));
                while(bis.read(buffer) != -1){
                    os.write(buffer);
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(bis != null) {
                    bis.close();
                }
                if(os != null) {
                    os.flush();
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return new ResultVO(ResultCode.SUCCESS);
    }
}

其中我的返回值ResultVO是一个自定义返回值,如需要,具体的代码如下:

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

// 统一响应结果
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ResultVO<T> {
    // 响应码 默认1000成功
    private int code;
    // 响应信息 来说明响应情况
    private String msg;
    // 响应的具体数据
    private T data;

    public ResultVO(T data) {
        this(ResultCode.SUCCESS, data);
    }

    public ResultVO(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public ResultVO(ResultCode resultCode, T data) {
        this.code = resultCode.getCode();
        this.msg = resultCode.getMsg();
        this.data = data;
    }

    public ResultVO(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
        this.data = null;
    }
}
import lombok.Getter;

/**
 * 响应码枚举
 */
@Getter
public enum ResultCode {

    SUCCESS(1000, "操作成功"),

    FAILED(1001, "响应失败"),

    VALIDATE_FAILED(1002, "参数校验失败"),

    NO_RESULT(1003, "未查询到相关信息"),

    MES_ERROR(1004, "未查询到相关信息"),

    NO_AUTHORITY(1005, "无权限"),

    DATA_EXIST(1006, "数据已存在"),

    ERROR(5000, "未知错误"),

    FILE_UPLOAD_ERROR(5001, "文件上传失败");


    private int code;
    private String msg;

    ResultCode(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

以下截图为我下载成功的截图文件
在这里插入图片描述

结语

以上就是我vue+springboot使用文件流实现文件下载的具体步骤

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐