poi向前端返回excel,有两种方法,先介绍简单粗暴的,就是最常用的直接用流向浏览器返回文件,比较简单粗暴,前端直接使用get方法即可,主要是后台的操作。
前端页面:
window.location.href="这里写路径,有参数的话也可以带上";
后台java代码,注意一下火狐浏览器的文件名的特殊处理:
/**
* 下载材料excel方法1,该方法暂时没启用 2020年3月12日 14:33:26
* excel
* @param req
* @param res
*/
@RequestMapping(method={RequestMethod.GET, RequestMethod.POST,RequestMethod.HEAD},value="getMaterialsExcel",produces="application/json")
public void getMaterialsExcel(HttpServletRequest req,HttpServletResponse res){
ServletOutputStream sos = null;
try{
logger.debug("************************开始下载材料excel*******************");
// 不用分页了,注意要带上过滤条件
Map<String, Object> param = new HashMap<String,Object>(); // 查询的过滤条件
param.put("productName", req.getParameter("productName"));
param.put("model", req.getParameter("model"));
param.put("productStatus", req.getParameter("productStatus"));
res.setContentType("application/json");
res.setCharacterEncoding("utf-8");
// service中得到具体业务相关的HSSFWorkbook
HSSFWorkbook wb = downloadExcelService.getMaterialsExcel(param);
String fileName = "测试测试.xls";
String agent = req.getHeader("USER-AGENT").toLowerCase();
String uncodeFileNameString = "";
if(agent.contains("firefox")){
// 火狐
uncodeFileNameString = "=?UTF-8?B?" + (new String(Base64Utils.encodeToString(fileName.getBytes("UTF-8")))) + "?=";
logger.debug("火狐浏览器");
}else{
// 其他
uncodeFileNameString = URLEncoder.encode(fileName, "UTF-8");
uncodeFileNameString = uncodeFileNameString.replace("+", "%20"); // 空格被转为了 "+" ,要转成utf-8的空格符号 "%20"
logger.debug("不是火狐浏览器");
}
res.setContentType("application/octet-stream;charset=UTF-8");
res.setHeader("Content-disposition", "attachment; filename=" + uncodeFileNameString);
sos = res.getOutputStream();
wb.write(sos);
}catch(Exception e){
e.printStackTrace();
logger.error("下载材料excel时异常: ", e);
}finally{
if(sos != null){
try {
// sos是字节流,不用flush了,直接close
sos.close();
} catch (IOException e) {
e.printStackTrace();
logger.error("未正确关闭sos");
}
}
}
}
以上方法比较简单,缺点也是有的,最大的缺点是前端不能监控下载进度,无法显示loading进度条,用户容易多次点击下载按钮,很难做控制,就算在后台做并发处理,但是还是对服务器有一定的压力,因此再介绍第二种方法,写在下一篇文章吧