vue使用文件流下载文件
1.前端代码
上传的选择框
<el-table class="table"
:data="tableData"
style="width: 100%"
highlight-current-row
empty-text="下载测试"
cell-mouse-enter>
<el-table-column
label="附件"
width="">
<template slot-scope="scope">
<el-button
v-if="scope.row.attachmentsPath!=''"
@click="dowm(scope.$index, scope.row)"
type="text"
size="small">
下载
</el-button>
<span v-else>--</span>
</template>
</el-table-column>
</el-table>
dowm(index, rows) {//下载
this.axios({
method: 'post',
url: 'home/file/downLoadByPath',//后台请求路径
data: this.$qs.stringify({
name: rows.name,//参数name
path: rows.path//参数path
}),
responseType: 'blob'//这里一定要设置
}).then(response => {
var data = {//这里的data就是之前传的参数,用来截取文件名
name: rows.attachmentsName,
path: rows.attachmentsPath
};
this.download(data,response.data)//这一步很重要,后台返回的流在里面一层
}).catch((error) => {
console.log(error);
})
},
download (param,data) {
if (!data) {
return
}
let name = param.name
let path= param.path
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
//getFileName(name,path)这个根据文件名和文件后缀截取文件名的。
link.setAttribute('download', getFileName(name,path))
document.body.appendChild(link)
link.click()
window.URL.revokeObjectURL(link.href)
document.body.removeChild(link)//释放标签
},
2.后台java代码
@PostMapping("downLoadByPath")
@ApiOperation(value="根据路径下载文件,path为路径")
public void downLoadByPath(String path,HttpServletRequest request,HttpServletResponse response) {
//这里的根据用户上传的文件路径获取文件,方法根据各位自己的进行改进
//FileUtil.pathFormat(path)用来格式化文件路径,全部用/表示
File file = getUpLoadFile(FileUtil.pathFormat(path));
if(!file.exists()||file.isDirectory())return;
InputStream in= null;
OutputStream out= null;
byte[] buffer = null;
try {
in= new BufferedInputStream(new FileInputStream(file));
buffer = new byte[in.available()];
response.reset();
// 设置response的Header
response.addHeader("Content-Length", "" + file.length());
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
out= new BufferedOutputStream(response.getOutputStream());
in.read(buffer);//直接读
out.write(buffer);//写到页面
out.flush();//刷一下
} catch (IOException e) {
throw new ServiceException("下载异常");
}finally {//流的关闭
try {
if(in!=null)in.close();
if(out!=null)out.close();
} catch (IOException e) {
throw new ServiceException("流关闭异常");
}
}
}
这里面可以使用try-with-resource语法糖,但是我不确定try-with-resource会不会自动执行flush()方法。
3.结束
其实后台并没有多少难点,主要是前面vue处理blob是发现返回的data在response.data里面这里才是最坑的,记录于此。
本文为作者原创,转载请申明出处!