Java后台Controller实现文件下载,支持多种浏览器
1.0业务场景实战
代码
参数:
1.filePath:文件的绝对路径(d:\download\a.xlsx)
2.fileName(a.xlsx)
3.编码格式(GBK)
4.response、request不介绍了,从控制器传入的http对象
代码片
.
//控制器
@RequestMapping(UrlConstants.BLACKLIST_TESTDOWNLOAD)
public void downLoad(String filePath, HttpServletResponse response, HttpServletRequest request) throws Exception {
boolean is = myDownLoad("D:\\a.xlsx","a.xlsx","GBK",response,request);
if(is)
System.out.println("成功");
else
System.out.println("失败");
}
//下载方法
public boolean myDownLoad(String filePath,String fileName, String encoding, HttpServletResponse response, HttpServletRequest request){
File f = new File(filePath);
if (!f.exists()) {
try {
response.sendError(404, "File not found!");
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
String type = fileName.substring(fileName.lastIndexOf(".") + 1);
//判断下载类型 xlsx 或 xls 现在只实现了xlsx、xls两个类型的文件下载
if (type.equalsIgnoreCase("xlsx") || type.equalsIgnoreCase("xls")){
response.setContentType("application/force-download;charset=UTF-8");
final String userAgent = request.getHeader("USER-AGENT");
try {
if (StringUtils.contains(userAgent, "MSIE") || StringUtils.contains(userAgent, "Edge")) {// IE浏览器
fileName = URLEncoder.encode(fileName, "UTF8");
} else if (StringUtils.contains(userAgent, "Mozilla")) {// google,火狐浏览器
fileName = new String(fileName.getBytes(), "ISO8859-1");
} else {
fileName = URLEncoder.encode(fileName, "UTF8");// 其他浏览器
}
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage(), e);
return false;
}
InputStream in = null;
OutputStream out = null;
try {
//获取要下载的文件输入流
in = new FileInputStream(filePath);
int len = 0;
//创建数据缓冲区
byte[] buffer = new byte[1024];
//通过response对象获取outputStream流
out = response.getOutputStream();
//将FileInputStream流写入到buffer缓冲区
while((len = in.read(buffer)) > 0) {
//使用OutputStream将缓冲区的数据输出到浏览器
out.write(buffer,0,len);
}
//这一步走完,将文件传入OutputStream中后,页面就会弹出下载框
} catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
} finally {
try {
if (out != null)
out.close();
if(in!=null)
in.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return true;
}else {
logger.error("不支持的下载类型!");
return false;
}
}
实现效果
1.火狐浏览器效果
2.chrome效果,自动下载
2.0 核心下载讲解
- 将以下代码写在控制器即可
//1.获取流InputStream(从本地文件也好,从第三方也罢)
InputStream in = MinioUtil.myDownload("xxxxx");
//InputStream in = new FileInputStream(new File("/aaa.txt"));
String fileName = "myFileName.txt";
//2.防止文件名编码错误,给文件名设置字符编码
fileName = URLEncoder.encode(fileName, "UTF8");
//3.告诉浏览器是下载
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
//4.流输出 (分两种方式、原理一样)
//a方法.(这个包下面这个工具类)package org.apache.commons.io;
IOUtils.copy(in, response.getOutputStream());
//b方法.手动输出,等价于上面a方法
OutputStream out = null;
try {
int len = 0;
//创建数据缓冲区
byte[] buffer = new byte[1024];
//通过response对象获取outputStream流
out = response.getOutputStream();
//将FileInputStream流写入到buffer缓冲区
while((len = in.read(buffer)) > 0) {
//使用OutputStream将缓冲区的数据输出到浏览器
out.write(buffer,0,len);
}
//这一步走完,将文件传入OutputStream中后,页面就会弹出下载框
} catch (Exception e) {
return "下载文件失败!";
} finally {
try {
//关闭流
if (out != null)
out.close();
if (in != null)
in.close();
} catch (Exception e) {
return "下载文件失败!";
}
}
四行代码搞定下载
//1.获取输入流:
InputStream in = new FileInputStream(new File("/aaa.txt"));
//2.将2、3步骤合并:
response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF8"));
//3.输出流:
IOUtils.copy(in, response.getOutputStream());
//4.在finally中关闭流
in.close();