一般来说,我们点击一个网页上可以访问到的excel文件,就可以直接下载保存该文件,但是文件的名称一般都是一个处理过后保存在数据库的值,如果我们需要下载文件时候将文件名改为自己需要的名称怎么办呢?
我的想法是以输入输出流的方式来处理,前端访问接口,从数据库取出自己所需要的ulr地址,通过new URL(url).openConnection()getInputStream()得到输入流,输出流写入输出流的字节返回,js处理输出流。
下面是controller的处理
@RequestMapping("/download")
@ResponseBody
public void download(HttpServletResponse response,HttpServletRequest request) {
String url = "";
String fileName = "";
OutputStream out = null;
InputStream in = null;
try {
//从数据库获取模板链接,文件名等其他信息
List<BaseFile> list = baseFileService.selectBaseFileById("9c3df32a-0c97-11ec-b8e8-0800278efc65");
if (list != null && list.size()>0){
//没有使用实体类封装,看起来有点怪哈哈哈
Map<String, Object> map = (Map)list.get(0);
//文件链接
url += map.get("fileUrl");
//文件名
fileName = map.get("fileName").toString();
//设置请求头,适配火狐浏览器,防止乱码问题
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
if (request.getHeader("user-agent").toLowerCase().contains("firefox")){
response.setHeader("Content-Dispostion","attachment;filename="+new String(fileName.getBytes("UTF-8"),"ISO-8859-1"));
}else {
response.setHeader("Content-Dispostion","attachment;filename="+URLEncoder.encode("utf-8","UTF-8"));
}
}
//得到输出流
out = response.getOutputStream();
//获取服务端生成的excel文件 url地址一定是可以通过网站访问到的
in = new URL(url).openConnection().getInputStream();
//输出文件
int b;
while((b=in.read())!=-1){
out.write(b);
}
//关闭输入输出流
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
logger.error("=====获取模板失败" + e.getMessage());
}
}
前端处理输出流的方式
function downloadExample(){
//XMLHttpRequest对象是和后台交互使用的
var xhr = new XMLHttpRequest();
xhr.open("POST", "framework/export/download.do", true);
xhr.responseType = "blob";
xhr.onload = function () {
var content = xhr.response;
//此处相当于用a标签来接受流
var elink = document.createElement('a');
//默认下载文件的name
elink.download = "test.xlsx";
elink.style.display = 'none';
//Blob对象就是包含有只读原始数据的类文件对象。Blob对象中的数据并不一定得是JavaScript中的原生形式。
var blob = new Blob([content]);
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
//处理完成就移除元素,以免占用内存
document.body.removeChild(elink);
};
//XMLHttpRequest对象发送请求
xhr.send();
}
至此就完成了一次excel下载操作了啊!看看效果吧!
最后本人还有一点疑惑,希望大佬能帮我解答!!!!
new URL(url).openConnection().getInputStream()
此处的url如果是外网能访问到的excel文件地址能正常得到流对象,但是我使用nginx代理本地的资源地址(外网无法正常访问)是无法正常得到流的,一直很疑惑!!!希望大佬能help me!!