前言:
最近有给分配一个任务,实现一个下载功能,前提是当在指定的目录下去查找固定名字的文件,如果存在则直接读取文件流在返回给浏览器,如果没有才去执行数据库去查,然后备份并输出到浏览器进行下载.
就这其中一个简单的功能,下面对这个部分进行实现。
JSP页面:
JSP代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <c:if test="${page.list != null && fn:length(page.list) > 0}"> <c:forEach var="run" items="${page.list}" varStatus="st"> <tr> <td style="text-align: center">${run.between}</td> <td style="text-align: center">${run.typeNo}</td> <td style="text-align: center">${run.status}</td> <td style="text-align: center">${run.recall}</td> <td style="text-align: center">${run.precision}</td> <td style="text-align: center">${run.kind}</td> <td class="td-manage" style="text-align: center"> <a title="下载" href="/CategoryTestRunData/downLoad?id=${run.id}"> <i class="layui-icon layui-icon-download-circle"></i> </a> </td> </tr> </c:forEach> </c:if>
|
说明:在测试的时候发现下载这里如果写Ajax异步请求下载话这个是无法请求的,所以这里写直链。
控制器:
控制层代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
@ResponseBody @RequestMapping("/downLoad") public void downLoad(String id, HttpServletResponse response, HttpServletRequest request) throws IOException { log.info("Excel表下载导出,传入参数:"+id); String dist = "/data/download/"; File fileList = new File(dist); if (!fileList.exists()){ fileList.mkdirs(); } String[] list = fileList.list(); boolean isExist = true; for (String name_id : list) { String sub_name = StringUtils.substring(name_id,0,name_id.lastIndexOf(".")); if (StringUtils.equals(sub_name,id)){ FileInputStream fileInputStream = new FileInputStream(dist+name_id); OutputStream outputStream = response.getOutputStream(); final String userAgent = request.getHeader("USER-AGENT"); String finalFileName = null; if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")){ finalFileName = URLEncoder.encode(name_id,"UTF8"); System.out.println("IE浏览器"); }else if(StringUtils.contains(userAgent, "Mozilla")){ finalFileName = new String(name_id.getBytes(), "ISO8859-1"); }else{ finalFileName = URLEncoder.encode(name_id,"UTF8"); } response.reset(); response.setContentType("application/x-download"); response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName+ ""); byte[] bytes = new byte[2048]; int len = 0; while ((len = fileInputStream.read(bytes))>0){ outputStream.write(bytes,0,len); } fileInputStream.close(); outputStream.close(); return ; } } isExist = false; if (!isExist){ try{ ExcelWriter writer = ExcelUtil.getWriter(dist+id+".xlsx");
List<RecordDown> recordList = categoryTestRunDataService.getDownLoadList(Long.parseLong(id)); log.info("返回数据:"+JSON.toJSONString(recordList)); if (recordList.size() == 0){ } writer.addHeaderAlias("mercNum","商户编号"); writer.addHeaderAlias("triggerTime","风险类别触发时间"); writer.addHeaderAlias("isRisk","是否风险商户"); writer.addHeaderAlias("kind","对应风险种类"); writer.addHeaderAlias("createHisTime","商户入网时间"); writer.addHeaderAlias("region","商户所属地区"); for (int i = 0; i < 6; i++) { writer.setColumnWidth(i,35); } writer.write(recordList, true); writer.close();
ExcelWriter writerToBrowser = ExcelUtil.getWriter(true); writerToBrowser.write(recordList, true); OutputStream outputStream = response.getOutputStream();
final String userAgent = request.getHeader("USER-AGENT"); String finalFileName = null; if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")){ finalFileName = URLEncoder.encode(id+".xlsx","UTF8"); System.out.println("IE浏览器"); }else if(StringUtils.contains(userAgent, "Mozilla")){ String fileName= id+".xlsx"; finalFileName = new String(fileName.getBytes(), "ISO8859-1"); }else{ finalFileName = URLEncoder.encode(id+".xlsx","UTF8"); } response.reset(); response.setContentType("application/x-download"); response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName+ ""); writerToBrowser.flush(outputStream, true); writerToBrowser.close(); IoUtil.close(outputStream); }catch (Exception e){ e.printStackTrace(); log.info("错误信息:"+e); } }
}
|
说明:项目实现逻辑
先去指定路径查找,是否有指定目录,是否有以ID为名的文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| String dist = "/data/download/"; File fileList = new File(dist); if (!fileList.exists()){ fileList.mkdirs(); } String[] list = fileList.list(); boolean isExist = true; for (String name_id : list) { String sub_name = StringUtils.substring(name_id,0,name_id.lastIndexOf(".")); if (StringUtils.equals(sub_name,id)){ } }
|
如果存在以ID为名的文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| FileInputStream fileInputStream = new FileInputStream(dist+name_id); OutputStream outputStream = response.getOutputStream(); final String userAgent = request.getHeader("USER-AGENT"); String finalFileName = null; if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")){ finalFileName = URLEncoder.encode(name_id,"UTF8"); System.out.println("IE浏览器"); }else if(StringUtils.contains(userAgent, "Mozilla")){ finalFileName = new String(name_id.getBytes(), "ISO8859-1"); }else{ finalFileName = URLEncoder.encode(name_id,"UTF8"); } response.reset(); response.setContentType("application/x-download"); response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName); byte[] bytes = new byte[2048]; int len = 0; while ((len = fileInputStream.read(bytes))>0){ outputStream.write(bytes,0,len); } fileInputStream.close(); outputStream.close(); return ;
|
当指定文件目录没有目标文件名时去查询相关数据,进行指定路径备份。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| ExcelWriter writer = ExcelUtil.getWriter(dist+id+".xlsx");
List<RecordDown> recordList = categoryTestRunDataService.getDownLoadList(Long.parseLong(id)); log.info("返回数据:"+JSON.toJSONString(recordList)); if (recordList.size() == 0){ }
writer.addHeaderAlias("me**Num","商**号"); writer.addHeaderAlias("tr**rTime","风险****时间"); writer.addHeaderAlias("is**sk","是否**商户"); writer.addHeaderAlias("k**d","对应**种类"); writer.addHeaderAlias("cre****sTime","商户**时间"); writer.addHeaderAlias("re**on","商户**地区");
for (int i = 0; i < 6; i++) { writer.setColumnWidth(i,35); }
writer.write(recordList, true);
writer.close();
|
备份完成后再将输出到浏览器,具体代码和上方(2.如果存在以ID为名的文件。)的逻辑相同。这里不再赘述。
下载结果。
| 商号 | 风险时间 | 是否商户 | 对应种类 | 商户时间 | 商户地区 |
| ——: | ————————-: | ————: | ————: | ————————-: | ————: |
| 123 | 2020-04-10 11:31:32 | 是 | ** | 2020-04-10 11:31:32 | 商户 |
补充:一般情况下,我们在进行下载功能的时候需要告诉浏览器他的类型。
response.setContentType("application/x-download")
是文件而不是页面,设置浏览器自带下载功能添加文件名。
response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName+ "")
实现方式:
实现浏览器下载可以有两种方式:
方法一:
1 2 3 4 5 6 7
| <action name="toauctionExcelAction"class="theauctionaction"method="Excel Theauctioninfo"> <result name="success"type="stream"> <param name="contentType">application/vnd.ms-excel;charset=UTF-8</param> <param name="contentoisposition">attachment;filename="${auctionName}"</param> <param name="inputName">excelTheauctioninfo</param> </result> </action>
|
从这个配置可以看出来这个是Struts2里面的写法,Struts2每一个方法都会有一个action作为配置信息,这样子使得配置文件更为方法和繁琐。
方法二:
1 2 3 4
| response.reset(); response.setContentType("application/x-download"); response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName);
|
直接在控制层中传入参数HttpServletResponse response
利用response
设置头信息和文件类型下载,这样做的好处是只对这一个方法有效,不会对其他请求造成影响。