下载zip包有两种方式,一种是先压缩好要下载的文件放在服务器,点下载时直接下载到本地。但这会出现一个问题,那就是如果要压缩的文件过大,会导致页面卡顿,用户体验极差。所以使用在下载过程中动态的对要下载的文件进行压缩是一种极好的解决方案。
以下为部分代码
/** * * Description: 批量下载作业 * @author willem * @date 2021/10/26 */ public void downloadBatchWork(){ JSONObject person = this.getPersonFromCookie(); //教师名 下载时文件名可用 String personName = person.getString("person_name"); String homeWorkIds = getPara("homeWork_ids"); if (StringUtil.isEmpty(homeWorkIds)){ renderJson(this.getJsonResult(false,"homeWork_ids参数不能为空")); return; } SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); HttpServletResponse response = getResponse(); response.reset(); response.setCharacterEncoding("utf-8"); response.setContentType("multipart/form-data"); String name = personName +" " + dateFormat.format(new Date()) + ".zip"; String agent = getRequest().getHeader("USER-AGENT"); try { if (agent.contains("MSIE") || agent.contains("Trident")){ name = URLEncoder.encode(name,"utf-8"); }else { name = new String(name.getBytes("utf-8"),"ISO-8859-1"); } }catch (Exception e){ e.printStackTrace(); } response.setHeader("Content-Disposition","attachment;fileName="" + name + """); List<String[]> result = BoxHomeWorkModel.dao.downloadBatchWork(homeWorkIds); //设置压缩流,直接写入responder,实现边压缩边下载 ZipOutputStream zipOutputStream = null; try { zipOutputStream = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())); //设置压缩方法 zipOutputStream.setMethod(ZipOutputStream.DEFLATED); }catch (Exception e){ e.printStackTrace(); } DataOutputStream outputStream = null; try { for (int i = 0; i < result.size(); ++i){ String[] strings = result.get(i); File file = new File(strings[1]); zipOutputStream.putNextEntry(new ZipEntry(strings[0])); outputStream = new DataOutputStream(zipOutputStream); InputStream inputStream = new FileInputStream(file); byte[] bytes = new byte[100]; int length = 0; while ((length = inputStream.read(bytes)) != -1){ outputStream.write(bytes,0,length); } inputStream.close(); zipOutputStream.closeEntry(); } }catch (Exception e){ e.printStackTrace(); }finally { if (outputStream != null){ try { outputStream.flush(); outputStream.close(); zipOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } renderJson(this.getJsonResult(true,"下载成功")); }
下载过程,因为是动态压缩文件导致没办法先计算出压缩后的文件大小,没办法显示下载进度。但我认为这种方法比第一种对用户的体验会更好。