在浏览器端点击下载,会下载一个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);
}
}