在实际应用中,文件下载或导出报表的场景应该很常见,如Excel报表导出……如果文件较多时,用户往往希望文件能够打包进行下载,这个时候就需要对下载的文件进行压缩打包,再进行下载。针对这个场景,我写了个压缩文件打包下载的Demo,这里实现的是Excel文件的压缩下载,Excel生成用到了Apache的POI组件,压缩功能使用的JDK自带API,具体实现代码如下:
一、Controller类
/**
* 压缩包下载控制器
* @author wdmcygah
*
*/
@Controller
@RequestMapping("/zip")
public class ZipController {
/**
* 压缩文件下载处理
*/
@RequestMapping("/download")
public ModelAndView downloanExcel(){
List<UserInfo> list = new ArrayList<UserInfo>();
UserInfo userInfo = new UserInfo();
userInfo.setPassword("0000");
userInfo.setUserName("sdfas");
list.add(userInfo);
list.add(userInfo);
list.add(userInfo);
list.add(userInfo);
Map<String,List<UserInfo>> map = new HashMap<String, List<UserInfo>>();
map.put("infoList", list);
ZipView ve = new ZipView();
return new ModelAndView(ve,map);
}
}
二、View类
/**
* 下载Excel视图
*
* @author wdmcygah
*
*/
public class ZipView extends AbstractView {
@Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
HSSFWorkbook b1 = generateExcel(model);
HSSFWorkbook b2 = generateExcel(model);
File file = getFile();
ZipUtils.zip(getFile(), b1,b2);
response.setContentType("application/octet-stream");
//这里为避免下载时中文乱码,需要进行url编码
String name = URLEncoder.encode("压缩.zip", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename="
+ name);
OutputStream os = response.getOutputStream();
IOUtils.copy(new FileInputStream(file), os);
os.flush();
os.close();
file.delete();
}
private HSSFWorkbook generateExcel( Map<String,Object> model){
HSSFWorkbook result = null;
@SuppressWarnings("unchecked")
List<UserInfo> list = (List<UserInfo>) model.get("infoList");
if (list != null && list.size() != 0) {
result = new HSSFWorkbook();
int len = list.size();
Sheet sheet = result.createSheet();
// 第一行文字说明
Row row = sheet.createRow(0);
Cell cell = row.createCell(0, Cell.CELL_TYPE_STRING);
cell.setCellValue("用户名");
cell = row.createCell(1, Cell.CELL_TYPE_STRING);
cell.setCellValue("密码");
//下面是具体内容
for (int i = 0; i < len; i++) {
row = sheet.createRow(i + 1);
cell = row.createCell(0, Cell.CELL_TYPE_STRING);
cell.setCellValue(list.get(i).getUserName());
cell = row.createCell(1, Cell.CELL_TYPE_STRING);
cell.setCellValue(list.get(i).getPassword());
}
}
return result;
}
private File getFile(){
String targetPath = "/ziptarget/zip/";
File file = new File(targetPath);
if( !file.exists() ){
file.mkdirs();
}
String fileName = "test.zip";
File f = new File(targetPath+fileName);
if( !f.exists() ){
try {
File.createTempFile("001", ".zip");
} catch (IOException e) {
e.printStackTrace();
}
}
return f;
}
}
三、压缩工具类
/**
* 使用JDK自带的Zip处理类进行文件的压缩与解压
*
*/
public class ZipUtils {
/**
* 对Excel文件进行压缩
*
* @param wb
*/
public static void zip(File targetFile, HSSFWorkbook... wbs) {
if (wbs == null || wbs.length == 0) {
return;
}
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(new FileOutputStream(targetFile));
for (int i = 0; i < wbs.length; i++) {
ZipEntry entry = new ZipEntry("文件" + i + ".xls");
// 设置压缩包的入口
zos.putNextEntry(entry);
wbs[i].write(zos);
zos.flush();
}
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、测试页面
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h3>测试下载Excel功能</h3>
<form action="file/download.htm" enctype="multipart/form-data" method="post">
<input type="submit" value="下载Excel"></input>
</form>
<h3>测试上传Excel功能</h3>
<form action="file/upload.htm" enctype="multipart/form-data" method="post">
<input type="file" name="file"></input>
<input type="submit" value="上传Excel"></input>
</form>
<h3>测试Excel的打包下载功能</h3>
<form action="zip/download.htm" enctype="multipart/form-data" method="post">
<input type="submit" value="下载Excel打包文件"></input>
</form>
</body>
</html>
完整源码可见我的Github地址:https://github.com/wdmcygah/research-spring
代码在Chrome浏览器下测试通过。