文件压缩后下载

最近项目里面,增加一个文件压缩下载的功能。拿出来跟大家分享。。。

项目框架:springmvc+spring+mybatis

  • jsp页面下载按钮
<a title="下载" href="${path }/admin/report-task/download?id=${item.id}" 
	class="btn btn-success radius size-S" style="text-decoration:none;">
<i class="Hui-iconfont Hui-iconfont-yundown"></i>
</a>
  • 控制层下载方法,将上传后的文件拷贝到临时文件夹下面,生成压缩包,执行下载操作:
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

//下载方法,请忽略业务逻辑部分
@RequestMapping("/download")
@ResponseBody
public void donwload(@RequestParam(value="id")Integer id,
		HttpServletResponse response) throws IOException{
	OrgReportTask entity = this.orgReportTaskService.selectByPrimaryKey(id);
	OrgReportObject param = new OrgReportObject();
	param.setTaskId(id);
	List<OrgReportObjectViewVo> list = this.orgReportObjectService.getList(param);
	//任务ID,根据任务ID查询上报支部对象,根据支部上报对象获取下载文件
	//创建任务名称临时文件夹
	String rootPath = MyUploadUtils.getRootUploadPath(request);
	String taskPath = rootPath+"/temp/"+entity.getTaskName();
	File taskFile = new File(taskPath);
	if(!taskFile.exists()) {
		taskFile.mkdirs();
	}
	//创建组织名称临时文件夹,并将给组织上传文件,复制到临时文件夹
	for(OrgReportObjectViewVo vo : list) {
		String orgPath = taskPath + "/" + vo.getOrgName();
		File orgFile = new File(orgPath);
		if(!orgFile.exists()) {
			orgFile.mkdirs();
		}
		//拷贝文件对象到临时文件夹
		Map<String,Object> map = new HashMap<>();
		map.put("tableId", vo.getId());
		map.put("tableName", "org_report_object");
		List<BscFile> fileList = this.bscFileService.getFileListByMap(map);
		for(BscFile file:fileList) {
			File source = new File(rootPath+file.getFileUrl());
			File dest = new File(orgPath+"/"+file.getFileName());
			FileUtils.copyFile(source, dest);
		}
	}
	
	//生成压缩包,执行下载操作
	zipDownload(response, entity.getTaskName(), taskFile);
}

/**
 * 生成压缩包,执行下载操作
 * @param response
 * @param zipFileName 压缩包名称
 * @param sourceFile 待压缩文件路径
 */
private void zipDownload(HttpServletResponse response,String zipFileName,File sourceFile) {
	//响应头的设置
	response.reset();
	response.setCharacterEncoding("utf-8");
	response.setContentType("multipart/form-data");
	//设置压缩包的名字
	zipFileName = zipFileName + ".zip";
	//解决不同浏览器压缩包名字含有中文时乱码的问题
	String agent = request.getHeader("USER-AGENT");
	
	ZipOutputStream zipos = null;
	DataOutputStream os = null;
	InputStream is = null;
	try {
		if (agent.contains("MSIE")||agent.contains("Trident")) {
			zipFileName = java.net.URLEncoder.encode(zipFileName, "UTF-8");
		} else {
			zipFileName = new String(zipFileName.getBytes("UTF-8"),"ISO-8859-1");
		}
		response.setHeader("Content-Disposition", "attachment;fileName=\"" + zipFileName + "\"");
		//设置压缩流:直接写入response,实现边压缩边下载
		zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
		zipos.setMethod(ZipOutputStream.DEFLATED); //设置压缩方法 
		//循环将文件写入压缩流
		fileIterator(sourceFile, sourceFile.getName(), zipos, os, is);
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		try {
			if(is!=null) is.close();
			if(os!=null) os.close();
			if(zipos!=null) zipos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

/**
 * @description 递归调用遍历文件下文件
 * @param sourceFile 文件夹
 * @param zipPathTop 压缩文件夹内部目录最高层级
 * @param zipos
 * @param os
 * @param is
 */
public void fileIterator(File sourceFile,String zipPathTop,ZipOutputStream zipos,DataOutputStream os, InputStream is) {
	//循环将文件写入压缩流
	File[] deviceFiles = sourceFile.listFiles();
	if(deviceFiles != null && deviceFiles.length != 0){
		for(File file:deviceFiles) {//获取路径下各文件夹
			if(file.isDirectory()) {//判断是否是路径,遍历路径
				fileIterator(file,zipPathTop,zipos,os,is);
			}else {//文件,直接压缩
				try {
					//压缩后的文件保留现有目录结构
					String zipPath =file.getPath().substring(file.getPath().indexOf(zipPathTop));
					zipos.putNextEntry(new ZipEntry(zipPath));
					os = new DataOutputStream(zipos);
					is = new FileInputStream(file);
					byte[] b = new byte[100];
					int length = 0;
					while((length = is.read(b))!= -1){
						os.write(b, 0, length);
					}
					os.flush();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 写在最后,文件下载完成后,可以删除生成的临时文件。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值