Java代码返回文件流
@GET
@Path("/ftp/download")
@Secured(loginCheck = false)
public Response download(@QueryParam("filepath") String filepath) {
try {
String name = "";
if (filepath.contains("http://")) {
String[] str = filepath.split("/");
name = str[str.length - 1];
} else {
String[] split = filepath.split("_");
name = split[split.length - 1];
}
URL url = new URL(filepath);
URLConnection urlConnection = url.openConnection();
return Response
.ok((StreamingOutput) output -> StreamUtils.copy(urlConnection.getInputStream(), output))
.header("Content-disposition",
"attachment;filename=" + java.net.URLEncoder.encode(name, "UTF-8"))
/* .header("Content-Type",
URLConnection.getFileNameMap().getContentTypeFor(filepath))*/
.header("Cache-Control", "no-cache")
.build();
} catch (Exception ex) {
ex.printStackTrace();
return Response.status(Response.Status.NOT_FOUND).build();
}
}
代码解析:
1.
header("Content-disposition",
"attachment;filename=" + java.net.URLEncoder.encode(name, "UTF-8"))
给响应头设置内容内容类型,文件名
2.
URL url = new URL(filepath);
URLConnection urlConnection = url.openConnection();
return Response
.ok((StreamingOutput) output -> StreamUtils.copy(urlConnection.getInputStream(), output))
获取网上的文件,将网上的文件流作为输入流拷贝到响应输出流
Vue接受文件流并下载
async download(file) {
// window.location.href = this.url;
console.log(file)
console.log('11', this.fileList)
let { url } = this.fileList.filter(f => f.name === file.name)[0]
console.log(url)
var filePath = encodeURIComponent(url);
if (this.loading) return;
this.loading = true;
const res = await axios.get("/ftp/download?filepath=" + filePath, {
responseType: "blob"
}).finally(() => {
this.loading = false;
});
if (res.status != 200) {
this.$message.error("网络请求错误!");
return;
}
// 获取文件名(优先从响应头获取)
const filename = res.headers['content-disposition'].split('=')[1] || file.name
const extension = filename.split('.').pop().toLowerCase();
// 定义支持的 MIME 类型映射
const mimeTypeMap = {
// Word
'doc': 'application/msword',
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
// Excel
'xls': 'application/vnd.ms-excel',
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
// PDF
'pdf': 'application/pdf'
};
// 获取对应的 MIME 类型
const fileType = mimeTypeMap[extension];
console.log(fileType)
// 创建 Blob 对象 自动设置office文件的类型,避免office文件损坏
const blob = new Blob([res.data], fileType ? { type: fileType } : undefined);
//创建下载链接
const linkurl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = linkurl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(linkurl);
},
下载附件的要点:
1.请求加上配置
{
responseType: "blob"
}
设置接收的响应值类型,否则导致文件格式损坏,导致打不开
2.office文件最好在创建Blob时指定文件类型,否则也有可能打不开下载的附件
const blob = new Blob([res.data], fileType ? { type: fileType } : undefined);
3.创建下载链接时,要将下载链接加入document节点树里,不然看不见下载附件提示
//创建下载链接
const linkurl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = linkurl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(linkurl);