后台将流输出到浏览器,前端获取流,并设置文件名等信息。
后台
public void download(HttpServletResponse response, byte[] data, String showFileName) {
BufferedInputStream bis = null;
OutputStream os = null;
BufferedOutputStream bos = null;
try {
os = response.getOutputStream(); // 重点突出
bos = new BufferedOutputStream(os);
// 对文件名进行编码处理中文问题
String fileName = new String( showFileName.getBytes("gb2312"), "ISO8859-1");
response.reset(); // 重点突出
response.setCharacterEncoding("UTF-8"); // 重点突出
response.setContentType("application/x-msdownload");// 不同类型的文件对应不同的MIME类型 // 重点突出
// inline在浏览器中直接显示,不提示用户下载
// attachment弹出对话框,提示用户进行下载保存本地
// 默认为inline方式
response.setHeader("Content-Disposition", "attachment; filename="+fileName); // 重点突出
bos.write(data, 0, data.length);// 将文件发送到客户端
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex.getMessage());
} finally {
// 特别重要
// 1. 进行关闭是为了释放资源
// 2. 进行关闭会自动执行flush方法清空缓冲区内容
try {
if (null != bis) {
bis.close();
bis = null;
}
if (null != bos) {
bos.close();
bos = null;
}
if (null != os) {
os.close();
os = null;
}
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
}
前端
download(){
this.getDicts("sys_normal_disable").then(res=>{
const temp = new Blob([res],{type:"application/vnd.ms-excel"});
const link = document.createElement("a");
link.href=URL.createObjectURL(temp);
link.setAttribute("download","阿萨德.xlsx");
document.body.appendChild(link);
link.click();
link.remove();
})
},
中文文件名,显示异常问题
http协议规定,header中的内容必须是iso8859-1编码。
下载文件时,设置文件名需要在header中设置,所以必须将文件名的编码转为iso8859-1编码。
response.setHeader("Content-Disposition",
"inline;fileName=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + "\"");