package org.springblade.common.utils; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Configuration; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; @Configuration public class ZipUtil { /** * zip解压 * * @param srcFile zip源文件 * @param destDirPath 解压后的目标文件夹 * @return list 解压文件的路径合集 * @throws RuntimeException 解压失败会抛出运行时异常 */ public static List unZipFiles(File srcFile, String destDirPath) throws RuntimeException { List list = new ArrayList<>(); long start = System.currentTimeMillis(); // 判断源文件是否存在 if (!srcFile.exists()) { throw new RuntimeException(srcFile.getPath() + "所指文件不存在"); } // 开始解压 ZipFile zipFile = null; try { zipFile = new ZipFile(srcFile, Charset.forName("GBK")); Enumeration entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry) entries.nextElement(); // 如果是文件夹,就创建个文件夹 if (entry.isDirectory()) { String dirPath = destDirPath + File.separator + entry.getName(); File dir = new File(dirPath); dir.mkdirs(); } else { // 如果是文件,就先创建一个文件,然后用io流把内容copy过去 File targetFile = new File(destDirPath + File.separator + entry.getName()); // 保证这个文件的父文件夹必须要存在 File parentFile = targetFile.getParentFile(); if (!parentFile.exists()) { parentFile.mkdirs(); } list.add(destDirPath + entry.getName()); targetFile.createNewFile(); // 将压缩文件内容写入到这个文件中 InputStream is = zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(targetFile); int len; byte[] buf = new byte[1024]; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } // 关流顺序,先打开的后关闭 fos.close(); is.close(); } } long end = System.currentTimeMillis(); } catch (Exception e) { throw new RuntimeException("unzip error from ZipUtils", e); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException e) { e.printStackTrace(); } } } return list; } /** * 压缩文件夹 * @param sourceFolderPath 压缩文件路径 * @param zipFilePath 压缩后包的路径 * @return */ public static boolean zipFolder(String sourceFolderPath, String zipFilePath) { File sourceFile = new File(sourceFolderPath); try ( FileOutputStream fos = new FileOutputStream(zipFilePath); ZipOutputStream zos = new ZipOutputStream(fos) ) { zipFile(sourceFile, sourceFile.getName(), zos); return true; } catch (IOException e) { e.printStackTrace(); } return false; } /** * 压缩文件夹 * @param sourceFolderPath 压缩文件路径 * @param zos zip输出流 * @return */ public static boolean zipFolder(String sourceFolderPath,ZipOutputStream zos) { File sourceFile = new File(sourceFolderPath); try { zipFile(sourceFile, sourceFile.getName(), zos); } catch (IOException e) { e.printStackTrace(); }finally { // 删除生成的文件 deleteDirectory(sourceFile); } return false; } /** * 删除文件夹下文件 * @param directoryToBeDeleted * @return */ public static boolean deleteDirectory(File directoryToBeDeleted) { File[] allContents = directoryToBeDeleted.listFiles(); if (allContents != null) { for (File file : allContents) { deleteDirectory(file); } } return directoryToBeDeleted.delete(); } /** * 将文件夹整体压缩 * @param fileToZip * @param fileName 文件名称 * @param zos * @throws IOException */ public static void zipFile(File fileToZip, String fileName, ZipOutputStream zos) throws IOException { if (fileToZip.isHidden()) { return; } if (fileToZip.isDirectory()) { if (fileName.endsWith("/")) { zos.putNextEntry(new ZipEntry(fileName)); zos.closeEntry(); } else { zos.putNextEntry(new ZipEntry(fileName + "/")); zos.closeEntry(); } File[] children = fileToZip.listFiles(); for (File childFile : children) { zipFile(childFile, fileName + "/" + childFile.getName(), zos); } return; } FileInputStream fis = new FileInputStream(fileToZip); ZipEntry zipEntry = new ZipEntry(fileName); zos.putNextEntry(zipEntry); byte[] bytes = new byte[1024]; int length; while ((length = fis.read(bytes)) >= 0) { zos.write(bytes, 0, length); } fis.close(); } /** * 设置导出zip的响应格式 * * @param request * @param response * @param fileZip zip的名字 * @param filePath zip的路径 * @throws UnsupportedEncodingException */ public static void downLoadFile(HttpServletRequest request, HttpServletResponse response, String fileZip, String filePath) throws UnsupportedEncodingException { //进行浏览器下载 final String userAgent = request.getHeader("USER-AGENT"); //判断浏览器代理并分别设置响应给浏览器的编码格式 String finalFileName = null; if (StringUtils.contains(userAgent, "MSIE") || StringUtils.contains(userAgent, "Trident")) { // IE浏览器 finalFileName = URLEncoder.encode(fileZip, "UTF8"); System.out.println("IE浏览器"); } else if (StringUtils.contains(userAgent, "Mozilla")) { // google,火狐浏览器 finalFileName = new String(fileZip.getBytes(), "ISO8859-1"); } else { // 其他浏览器 finalFileName = URLEncoder.encode(fileZip, "UTF8"); } // 告知浏览器下载文件,而不是直接打开,浏览器默认为打开 response.setContentType("application/x-download"); // 下载文件的名称 response.setHeader("Content-Disposition", "attachment;filename=\"" + finalFileName + "\""); ServletOutputStream servletOutputStream = null; try { servletOutputStream = response.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } DataOutputStream temps = new DataOutputStream( servletOutputStream); // 浏览器下载文件的路径 DataInputStream in = null; try { in = new DataInputStream( new FileInputStream(filePath)); } catch (FileNotFoundException e) { e.printStackTrace(); } byte[] b = new byte[2048]; // 之后用来删除临时压缩文件 File reportZip = new File(filePath); try { while ((in.read(b)) != -1) { temps.write(b); } temps.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (temps != null) { try { temps.close(); } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (reportZip != null) { // 删除服务器本地产生的临时压缩文件! reportZip.delete(); } try { servletOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { // 调用方法进行测试 } }