package com.zhgd.xmgl.util; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * @program: wisdomSite * @description: 生成压缩文件 (zip,rar 格式) * @author: Mr.Peng * @create: 2020-12-30 15:45 **/ @Slf4j public class CompressUtil { /** * @param path 要压缩的文件路径 * @param format 生成的格式(zip、rar)d */ public static void generateFile(String path, String format) throws Exception { File file = new File(path); // 压缩文件的路径不存在 if (!file.exists()) { throw new Exception("路径 " + path + " 不存在文件,无法进行压缩..."); } // 用于存放压缩文件的文件夹 String generateFile = file.getParent() + File.separator + "CompressFile"; File compress = new File(generateFile); // 如果文件夹不存在,进行创建 if (!compress.exists()) { compress.mkdirs(); } // 目的压缩文件 String generateFileName = compress.getAbsolutePath() + File.separator + "AAA" + file.getName() + "." + format; // 输入流 表示从一个源读取数据 // 输出流 表示向一个目标写入数据 // 输出流 FileOutputStream outputStream = new FileOutputStream(generateFileName); // 压缩输出流 ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream)); generateFile(zipOutputStream, file, ""); log.info("源文件位置:" + file.getAbsolutePath() + ",目的压缩文件生成位置:" + generateFileName); // 关闭 输出流 zipOutputStream.close(); } /** * @param out 输出流 * @param file 目标文件 * @param dir 文件夹 * @throws Exception */ private static void generateFile(ZipOutputStream out, File file, String dir) throws Exception { // 当前的是文件夹,则进行一步处理 if (file.isDirectory()) { //得到文件列表信息 File[] files = file.listFiles(); //将文件夹添加到下一级打包目录 out.putNextEntry(new ZipEntry(dir + "/")); dir = dir.length() == 0 ? "" : dir + "/"; //循环将文件夹中的文件打包 for (int i = 0; i < files.length; i++) { generateFile(out, files[i], dir + files[i].getName()); } } else { // 当前是文件 // 输入流 FileInputStream inputStream = new FileInputStream(file); // 标记要打包的条目 out.putNextEntry(new ZipEntry(dir)); // 进行写操作 int len = 0; byte[] bytes = new byte[1024]; while ((len = inputStream.read(bytes)) > 0) { out.write(bytes, 0, len); } // 关闭输入流 inputStream.close(); } } public static void exportZipFile(HttpServletResponse response, String sourceFilePath) { //文件名以时间戳作为前缀 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String filePrefix = sdf.format(new Date()); String downloadName = filePrefix + ".rar"; //将文件进行打包下载 try { OutputStream out = response.getOutputStream(); //接收压缩包字节 byte[] data = createZip(sourceFilePath); response.reset(); response.addHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Expose-Headers", "*"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + downloadName); response.addHeader("Content-Length", "" + data.length); response.setContentType("application/octet-stream;charset=UTF-8"); IOUtils.write(data, out); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } } private static byte[] createZip(String sourceFilePath) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipArchiveOutputStream zip = new ZipArchiveOutputStream(outputStream); //将目标文件打包成zip导出 File file = new File(sourceFilePath); //handlerFile(zip, file,""); addTarArchiveEntryToTarArchiveOutputStream(file, zip, ""); IOUtils.closeQuietly(zip); return outputStream.toByteArray(); } private static void addTarArchiveEntryToTarArchiveOutputStream(File file, ZipArchiveOutputStream tar, String prefix) throws IOException { String path = prefix; if (StringUtils.isNotEmpty(prefix)) { path = prefix + File.separator; } ZipArchiveEntry entry = new ZipArchiveEntry(file, path + file.getName()); if (file.isFile()) { entry.setSize(file.length()); tar.putArchiveEntry(entry); try (FileInputStream fileInputStream = new FileInputStream(file); BufferedInputStream input = new BufferedInputStream(fileInputStream);) { IOUtils.copy(input, tar); } tar.closeArchiveEntry(); } else { tar.putArchiveEntry(entry); tar.closeArchiveEntry(); if (StringUtils.isNotEmpty(prefix)) { prefix += File.separator + file.getName(); } else { prefix += file.getName(); } File[] files = file.listFiles(); if (files != null) { for (File f : files) { addTarArchiveEntryToTarArchiveOutputStream(f, tar, prefix); } } } } }