文件压缩后下载

    技术2022-07-10  160

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

    项目框架: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(); } } } } }

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

    Processed: 0.016, SQL: 9