Springboot_文件下载功能(前端后端)
遇到的问题:
- 文件下载后文件一直被破坏,无法正常打开
- 文件名乱码,如图
刚开始一直在纠结,是不是后端没有写对,然后导致下载不能使用
后来搜索了一些资料,发现后端没什么问题
然后就开始找到其他项目对比下载功能
哈哈哈哈哈哈哈
不会也只能靠这个方法去找问题了,就是有点笨,但总归找到了问题所在
下载功能后端代码:
@GetMapping("/annex")
public void downloadAnnex(ProcessFindReqVo processFindReqVo, HttpServletResponse response) throws IOException, HttpMediaTypeNotAcceptableException {
String filePath = "文件路径"; // 指定文件路径
if (StringUtils.isBlank(filePath)) {
return;
}
File file = new File(filePath);
if (!file.exists()) {
return;
}
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream;charset=UTF-8");
String fileName = URLEncoder.encode(file.getName(), StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
byte[] buffer = new byte[(int)file.length()];
FileInputStream fis = null;
OutputStream os = null;
try {
fis = new FileInputStream(file);
os = response.getOutputStream();
int i = -1;
while ((i = fis.read(buffer)) != -1) {
os.write(buffer, 0, i);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
下载功能前端代码
export async function downloadAnnex(data){
const res = await axios.get(`/scm/web/monthly/download/annex?id=`+data, {
responseType: 'blob'
})
const content = res.data
const blob = new Blob([content], { type: 'application/octet-stream' })
const contentDispositionHeader = res.headers['content-disposition'];
const fileName = contentDispositionHeader.split(';')
.map(item => item.trim())
.find(item => item.startsWith('filename='))
.substr('filename='.length);
let decodeName = decodeURI(fileName);
if ('download' in document.createElement('a')) { // 非IE下载
const elink = document.createElement('a')
elink.download = decodeName
elink.style.display = 'none'
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href) // 释放URL 对象
document.body.removeChild(elink)
} else { // IE10+下载
navigator.msSaveBlob(blob, decodeName)
}
}
- 说回刚开始的问题,下载时文件始终提示被破坏的原因:
export async function downloadAnnex(data){
这里应该使用async
关键字
const res = await axios.get
请求时也应该使用await
关键字,这样就可以使文件顺利下载,至于为什么还没有深究。。。(想以后研究,不知道以后还能不能想起来了😅) - 文件名始终乱码,就使用
decodeURI(fileName);
进行解码,之后就可以正确的展示中文字符了,前提时后端传输时已经设置了UTF-8
的编码