在浏览器端点击下载,会下载一个zip压缩包,里面包含多个Excel文件

      我暂且把从程序中下载压缩包分为三种类型,即三步下载,两步下载,一步下载。三步下载是指第一步先从数据库读取数据、写成文件,然后把文件们下载到本地磁盘;第二步是把文件们打成压缩包;第三步是把压缩包读取到程序中然后响应到浏览器。两步下载是指从数据库读取数据、写成文件再打成压缩包,然后把压缩包下载到本地磁盘,这是第一步;第二步是把压缩包读取到程序中然后响应到浏览器。一步下载是指程序从数据库读取数据、写成文件、转成流和响应到浏览器,都不用写到本地磁盘,只在内存中,一步输出压缩包。

本次先以多Excel文件打成Zip压缩包为例,其他文件格式后续发表。

3.一步下载

过程:在程序中生成Excel文件们,放到ByteOutputStream中,再把该流放到byte[]数组中,然后把数组写到zipEntry中,最后把zip压缩包的流都缓存到新的ByteOutputStream中(ByteArrayOutputStream也可以),把新建的流转成byte[],并响应到浏览器。

特点:文件在程序中生成;支持多文件格式暂用Excel为例

优点:无需写到本地服务器,不占用磁盘资源

难点:workBook的写出方式;zip实体的添加特性;IO流的特性


@RequestMapping("settleTransfer_downLoad")
	@ResponseBody
	public void downLoad(HttpServletRequest request,HttpServletResponse response,String downloadType,Model model) throws Exception{
		
			try {
				FlieToPackageResponse.mainTest(request,response);
			} catch (CHException e) {
				e.printStackTrace();
				response.getWriter().print("<script>alert('"+e.getErrInfo()+"');</script>");
				
			} catch (Exception e) {
				e.printStackTrace();
				response.getWriter().print("<script>alert('系统异常');</script>");
				
			}
		}



package com.yangjf.service.impl;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

public class FlieToPackageResponse {

	/**
	 * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
	 * (把多excel流直接生成到zip实体中,然后把压缩包<相应到浏览器>)
	 * (在声明excel的时候使用的WritableWorkbook,有wirte()方法,可以直接把信息写进流中;
	 * 如果申明WorkBook,只有write(io)方法,该方法把io信息流直接写成excel到本地)。
	 * @return
	 */
	public static boolean fileToZip(List<byte[]>bytes,HttpServletResponse response) {
		boolean flag = false;
		ZipOutputStream zos = null;
		ByteArrayOutputStream byteTest = new ByteArrayOutputStream(10*1024);
		try {
				zos = new ZipOutputStream(byteTest);
                if(bytes!=null&&bytes.size()>0)
                	for(int i=0;i<bytes.size();i++){
    					byte[] b=bytes.get(i);
    					// 创建ZIP实体,并添加进压缩包
    					ZipEntry zipEntry = new ZipEntry(i+".xls");
    					zos.putNextEntry(zipEntry);
    					// 读取待压缩的文件并写进压缩包里
    					zos.write(b);
    					/**
    					 * 下面多添加一个实体的原因是上面传流的时候,最后一个流不能关闭,所以下载最后一个文件不能下载,
    					 * 因此我多添加一个实体zipEntry,并调用putNextEntry关闭当前实体。
    					 */
    					if(i==bytes.size()-1){
    						ZipEntry zipEntryAdd = new ZipEntry(i+1 +".xls");
    						zos.putNextEntry(zipEntryAdd);
    					}
    				}
                
               byte[] byteT =byteTest.toByteArray();

               response.reset();
 			   response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("测试一步下载.zip", "UTF-8"));
 			   response.addHeader("Content-Length", "" + byteTest.size());
 			   OutputStream ous = new BufferedOutputStream(response.getOutputStream());
 			   response.setContentType("application/octet-stream");
 			   ous.write(byteT);
 			   ous.flush();
 			   ous.close();
                 
               
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			// 关闭流
			try {
				if (null != zos)
					zos.close();
				if(byteTest!=null)
                	byteTest.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		return flag;
	}

	public static void createExcel(ByteOutputStream bytes,int i) throws Exception {
		// /创建工作薄
		WritableWorkbook workbook = Workbook.createWorkbook(bytes);
		// 创建新的一页
		WritableSheet sheet = workbook.createSheet("First Sheet", 0);
		// 创建要显示的内容,创建一个单元格,第一个参数为列坐标,第二个参数为行坐标,第三个参数为内容
		Label xuexiao = new Label(0, 0, "学校");
		sheet.addCell(xuexiao);
		Label zhuanye = new Label(1, 0, "专业");
		sheet.addCell(zhuanye);
		Label jingzhengli = new Label(2, 0, "专业竞争力");
		sheet.addCell(jingzhengli);
		if(i==0){
			Label qinghua = new Label(0, 1, "清华大学");
			sheet.addCell(qinghua);
			Label jisuanji = new Label(1, 1, "计算机专业");
			sheet.addCell(jisuanji);
			Label gao = new Label(2, 1, "高");
			sheet.addCell(gao);
		}
		if(i==1){
			Label beida = new Label(0, 2, "北京大学");
			sheet.addCell(beida);
			Label falv = new Label(1, 2, "法律专业");
			sheet.addCell(falv);
			Label zhong = new Label(2, 2, "中");
			sheet.addCell(zhong);
		}
		if(i==2){
			Label ligong = new Label(0, 3, "北京理工大学");
			sheet.addCell(ligong);
			Label hangkong = new Label(1, 3, "航空专业");
			sheet.addCell(hangkong);
			Label di = new Label(2, 3, "低");
			sheet.addCell(di);
		}

		// 把创建的内容写入到输出流中,并关闭输出流
		workbook.write();
		workbook.close();
		bytes.close();

	}

//	public static void main(String[] args) throws Exception {
	public static void mainTest(HttpServletRequest request,HttpServletResponse response) throws Exception {
		ByteOutputStream bytes = new ByteOutputStream();
		ByteOutputStream bytes1 = new ByteOutputStream();
		ByteOutputStream bytes2 = new ByteOutputStream();
		createExcel(bytes,0);
		createExcel(bytes1,1);
		createExcel(bytes2,2);
		List<byte[]> listBytes = new ArrayList<byte[]>();
		byte[] b = bytes.getBytes();
		byte[] b1= bytes1.getBytes();
		byte[] b2= bytes2.getBytes();
		listBytes.add(b);
		listBytes.add(b1);
		listBytes.add(b2);
		fileToZip(listBytes,response);
		
	}

}