1)安装js-file-download



npm i -S js-file-download


2)编写下载的页面



<template>
<div>
<el-button @click="download">下载</el-button>
</div>
</template>

<script>
import fileDownload from 'js-file-download'
import request from '@/request'
export default {
methods: {
download() {
request.postDownload('file/download').then(res => {
const disposition = res.headers["content-disposition"]
//获取文件名
let fileName = disposition.substring(disposition.indexOf("filename=") + 9);
if (window.navigator.userAgent.indexOf("Firefox") > -1) {
fileName = fileName.substring(fileName.indexOf("-8?B?") + 5, fileName.indexOf("?="))
fileName = base64Util.decode(fileName);
} else {
fileName = decodeURIComponent(fileName);
}
fileDownload(res.data, fileName)
}).catch(err => {
console.log(err)
})
}
},

}

</script>

<style scoped>

</style>


这里网络请求使用的axios,对其进行了​​封装​​。下载的方法很简单,主要是获取响应头中的文件名

3)编写下载的工具类



package com.zys.demo.util;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

@Slf4j
public class FileUtil {

/**
* 通过流下载文件
*
* @param fileName 文件名
* @param response
* @throws IOException
*/
public static void downloadFile(String filePath, String fileName, HttpServletResponse response) throws IOException {
File file = new File(filePath + File.separator + fileName);
InputStream in = new FileInputStream(file);
//允许暴露content-disposition,默认不暴露
response.setHeader("Access-Control-Expose-Headers", "content-disposition");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/octet-stream");
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
int len = 0;
byte bytes[] = new byte[1024];
OutputStream out = response.getOutputStream();
while ((len = in.read(bytes)) > 0) {
out.write(bytes, 0, len);
}
in.close();
out.close();
}

}


需要注意的是必须设置响应头的Access-Control-Expose-Headers,也就是要暴露的信息,否则在前端无法获取到文件名。

4)编写下载的接口



package com.zys.demo.controller;

import com.zys.demo.util.FileUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@RequestMapping("/api/file")
public class FileController {

@PostMapping("/download")
public void downloadFile(HttpServletResponse response) throws IOException {
FileUtil.downloadFile("D://temp", "test.txt", response);
}
}


启动后,点击下载按钮即可下载。文件需事先存在于对应位置。