浏览器下载JAVA POI生成EXCLE放入ZIP中的二进制数据。内存中处理,无需落地本地,避免多次IO操作。

实现思路

一般实现标题中所说的zip文件下载,目前本人了解到的有两种:

1、将所有要压入到ZIP中的数据,优先落地至服务器临时指定位置。在这个过程中需要与服务器发生写入、读取、删除三次IO动作

遇到并发情况会暴露很多问题。

2、将所有存入zip文件的动作在内存中完成,直接将二进制数据提供给用户。

据我了解到的公司大部分,一般是通过第一种思路进行处理。

解决过程

1、poi excel生成过程  //代码不在展示

2、excel放入zip过程 

3、输出到网页端

框架信息/JAR信息

1、SSM

2、JDK1.7

3、POI 3.8(还不是稳定版本)

代码

@ResponseBody
	@RequestMapping(value = { "/downloadPerformanceTasksZip" })
	@AvoidDuplicateSubmission(needSaveToken = true)
	@BussAnnotation(moduleName = "", option = "")
	public  void downloadPerformanceTasksZip(PerformanceTasks performanceTasks,String  deptId,
											HttpServletResponse response){
		OrgList orglist =  orglistServiceI.findObjectByPK(deptId);
		//依据部门id查询出当前部门下得所有用户
		List  userList = userServiceI.listUserByDetptId(deptId);
		//查询出当前用户的所有数据
		
		try {
			//创建临时文件生成zip
			String filename = orglist.getOrgCnName()+".zip";
			//设置响应头
			response.addHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(filename, "UTF-8"));
	        response.setContentType("application/x-msdownload");
	    	ServletOutputStream servletOS;
	    	//获取到输出流
			servletOS = response.getOutputStream();
			//zip输入流声明
			ZipOutputStream zos = new ZipOutputStream(servletOS);
			//二进制输出流
			ByteArrayOutputStream ostream = null;
			//输入流
			InputStream is = null;
			for (Users users : userList) {
				List list =  performanceTasksServiceI.listAllPerformanceTasksByUserId(users.getUserId());
				if(list!=null&&list.size()>0){
					ostream = new ByteArrayOutputStream();
					//POI生成的 Workbook 对象
					Workbook wb = ExcleUtil.getExcel(users, list);
					//将获取到得转换为二进制数据 放入输入流中 
					wb.write(ostream);
					byte[] content = ostream.toByteArray();
					//二进制数据写入到输入流中
					is = new ByteArrayInputStream(content);
					//向zip中添加文件按信息
					zos.putNextEntry(new ZipEntry(users.getCnUserName()+".xls"));
					int bytesRead = 0;
					while ((bytesRead = is.read()) != -1) {
						zos.write(bytesRead);
					}
				}
				
			}
//			File zipFile = File.createTempFile(filename, ".zip");
//			FileOutputStream fos = new FileOutputStream(zipFile);
//			CheckedOutputStream cos = new CheckedOutputStream(fos, new Adler32());
			if(is!=null){
				is.close();
			}
			if(ostream!=null){
				ostream.close();
			}
			zos.closeEntry();
			zos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

如各位有更好的解决方案以及思路 欢迎留言分享

你可能感兴趣的:(POI)