- 这种会出现pdf,txt,jpg…这些常见格式的文件在web浏览器以预览的形式出现,而不是需要的下载
function downloadFile(url, fileName, parameter) {
return downFile(url, parameter).then((data) => {
if (!data || data.size === 0) {
Vue.prototype['$message'].warning('文件下载失败')
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName)
} else {
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()
document.body.removeChild(link) //下载完成移除元素
window.URL.revokeObjectURL(url) //释放掉blob对象
}
})
}
File file = new File(path);
if(!file.exists()){
response.setStatus(404);
throw new RuntimeException("文件不存在..");
}
InputStream inputStream = null;
OutputStream outputStream = null;
try {
response.reset();
outputStream = new BufferedOutputStream(response.getOutputStream());
inputStream = new BufferedInputStream(new FileInputStream(file));
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
outputStream.flush();
}
response.setContentLength((int )file.length());
response.setContentType("application/force-download");
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
} catch (IOException e) {
log.info("读取文件失败" + e.getMessage());
response.setStatus(404);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
上述代码有两个问题:
- java中发现response设置
contentType
无效 - js中先完整的获取二进制流,然后封装成blob文件对象,也就是先执行了文件下载请求,但是在客户端看不到过程,遇到较大文件时,用户无法感知,体验很差
解决办法:
- java中
改变下设置contentType
和获取输出流的顺序,如下
response.reset();
response.setContentLength((int )file.length());
response.setContentType("application/force-download");
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
outputStream = new BufferedOutputStream(response.getOutputStream());
inputStream = new BufferedInputStream(new FileInputStream(file));
- js中
不直接获取完整的二进制流,之前文件的相关设置是在前端做的,现在都放在后端
function downloadFile(url,filename){
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
document.body.appendChild(link)
link.click()
document.body.removeChild(link) //下载完成移除元素
window.URL.revokeObjectURL(url) //释放掉blob对象
}