我暂且把从程序中下载压缩包分为三种类型,即三步下载,两步下载,一步下载。三步下载是指第一步先从数据库读取数据、写成文件,然后把文件们下载到本地磁盘;第二步是把文件们打成压缩包;第三步是把压缩包读取到程序中然后响应到浏览器。两步下载是指从数据库读取数据、写成文件再打成压缩包,然后把压缩包下载到本地磁盘,这是第一步;第二步是把压缩包读取到程序中然后响应到浏览器。一步下载是指程序从数据库读取数据、写成文件、转成流和响应到浏览器,都不用写到本地磁盘,只在内存中,一步输出压缩包。
本次先以多Excel文件打成Zip压缩包为例,其他文件格式后续发表。
2.两步下载
特点:把多excel流直接生成到zip实体中,然后把压缩包保存到本地;把压缩包响应到浏览器
优点:比三步下载少下载Excel文件,只需要把zip流输出到本地
难点:ZipEntry的特性
第一步:在程序内生成Excel文件,把数据流写入到zip实体中,把zip输出到本地磁盘(有标注:第一步);
第二步:在磁盘读取zip文件,把文件流响应到浏览器端(有标注:第二步);
public static boolean fileToZip(Listbytes, String zipFilePath, String fileName) { boolean flag = false; FileOutputStream fos = null; ZipOutputStream zos = null; try { File zipFile = new File(zipFilePath + "/" + fileName + ".zip"); if (zipFile.exists()) { System.out.println(zipFilePath + "目录下存在名字为:" + fileName + ".zip" + "打包文件."); } else { if(!zipFile.exists()){ zipFile.getParentFile().mkdirs(); }//第一步 fos = new FileOutputStream(zipFile); zos = new ZipOutputStream(new BufferedOutputStream(fos)); if(bytes!=null&&bytes.size()>0) for(int i=0;i listBytes = new ArrayList (); byte[] b = bytes.getBytes(); byte[] b1= bytes1.getBytes(); listBytes.add(b); listBytes.add(b1); String zipFilePath = "F:\\update"; String fileName = "tp-admin"; fileToZip(listBytes, zipFilePath, fileName); }
//第二步
//读取zip文件,并下载到浏览器 File file = new File(filePath + "/" + fileName); fis = new FileInputStream(file); byte [] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); response.reset(); response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); response.addHeader("Content-Length", "" + file.length()); OutputStream ous = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); ous.write(buffer); ous.flush(); ous.close();