JAVA生成Zip文件并导出

一 : 需解决问题

最近碰到业务需要做一些特殊的导出。
大致就是:需要根据某些维度,导出多个Excel,Word,PDF等等这种文件,并且一次性导出。
这样的话,就不能用正常的导出去处理,而需要去做一个压缩导出的操作。
附上导出Excel,Word,PDF的链接:
JAVA导出Excel文件:https://blog.csdn.net/qq_38254635/article/details/126691175
JAVA根据模板生成WORD文件并导出:https://blog.csdn.net/qq_38254635/article/details/103952823
JAVA根据PDF文件生成图片:https://blog.csdn.net/qq_38254635/article/details/112029941
JAVA根据模板生成PDF文件并导出:https://blog.csdn.net/qq_38254635/article/details/103919024

二 : 需要实现的效果

原文件
JAVA生成Zip文件并导出_第1张图片
生成文件
JAVA生成Zip文件并导出_第2张图片
压缩后,是否删除,可通过参数控制。

三 : 导出ZIP工具类

直接上代码,ZipUtil工具类

package com.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class ZipUtil {

    /**
     * 设置返回前端文件名
     * @param response response
     * @param fileName 文件名,包含后缀
     * @return OutputStream
     * @throws Exception Exception
     */
    public static OutputStream getOutputStreamFileName(HttpServletResponse response, String fileName) throws Exception{
        response.reset();
        String fileType = fileName.split("\\.")[1].toLowerCase();
        switch (fileType){
            case "doc":
                response.setContentType("application/msword");//设置生成的文件类型
                break;
            case "docx":
                response.setContentType("application/msword");//设置生成的文件类型
                break;
            case "xls":
                response.setContentType("application/vnd.ms-excel");//设置生成的文件类型
                break;
            case "xlsx":
                response.setContentType("application/vnd.ms-excel");//设置生成的文件类型
                break;
            case "pdf":
                response.setContentType("application/pdf");//设置生成的文件类型
                break;
            case "zip":
                response.setContentType("application/zip");//设置生成的文件类型
                break;
            case "dbf":
                response.setContentType("application/x-dbf");//设置生成的文件类型
                break;
            default:
                return response.getOutputStream();
        }
        response.setCharacterEncoding("UTF-8");//设置文件头编码方式和文件名
        response.setHeader("Content-Disposition", "attachment;filename=" +
                new String(URLEncoder.encode(fileName, "UTF-8").getBytes("utf-8"), "ISO8859-1"));
        return response.getOutputStream();
    }

    /**
     * 压缩文件
     * @param response response
     * @param filePath 文件路径
     * @param fileName 压缩生成文件名
     * @throws IOException IOException
     */
    public static void zipDateFile(HttpServletResponse response, String filePath, String fileName) throws Exception {
        if (StringUtils.isEmpty(filePath) || !new File(filePath).exists()) return;
        zipDateFile(response, getAllFile(filePath), fileName, true);
    }

    /**
     * 压缩文件
     * @param response response
     * @param fileList 文件集合
     * @param fileName 压缩生成文件名
     * @throws IOException IOException
     */
    public static void zipDateFile(HttpServletResponse response, List<File> fileList, String fileName, boolean deleteSourceFile) throws Exception {
        getOutputStreamFileName(response, fileName);
        ServletOutputStream servletOutputStream = response.getOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(servletOutputStream);
        zipFile(fileList, zipOutputStream, true);
        try {
            zipOutputStream.close();
        } catch (IOException e) {
            log.error("流关闭失败", e);
        }
    }

    /**
     * 压缩导出
     * @param fileList 文件列表
     * @param zipOutputStream zip流
     * @throws IOException IOException
     */
    public static void zipFile(List<File> fileList, ZipOutputStream zipOutputStream, boolean deleteSourceFile) throws IOException {
        byte[] buffer = new byte[1024];
        for (File file : fileList) {
            if (file.exists()) {
                if (file.isFile()) {
                    try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));) {
                        zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
                        int size = 0;
                        while ((size = bis.read(buffer)) > 0) {
                            zipOutputStream.write(buffer, 0, size);
                        }
                        zipOutputStream.closeEntry();
                    } finally {
                        if(deleteSourceFile) file.delete();
                    }
                } else {
                    File[] files = file.listFiles();
                    if(null == files) continue;
                    List<File> childrenFileList = Arrays.asList(files);
                    zipFile(childrenFileList, zipOutputStream, deleteSourceFile);
                }
            }
        }
    }

    /**
     * 获取指定文件夹下所有文件,不含文件夹里的文件
     * @param filePath 文件路径
     * @return fileList
     */
    public static List<File> getAllFile(String filePath) {
        if (StringUtils.isEmpty(filePath)) return null;
        return getAllFile(new File(filePath));
    }

    /**
     * 获取指定文件夹下所有文件,不含文件夹里的文件
     * @param dirFile 文件夹
     * @return fileList
     */
    public static List<File> getAllFile(File dirFile) {
        // 如果文件夹不存在或着不是文件夹,则返回 null
        if (Objects.isNull(dirFile) || !dirFile.exists() || dirFile.isFile()){
            return null;
        }
        File[] childrenFiles = dirFile.listFiles();
        if (Objects.isNull(childrenFiles) || childrenFiles.length == 0){
            return null;
        }
        List<File> files = new ArrayList<>();
        for (File childFile : childrenFiles) {
            // 如果是文件,直接添加到结果集合
            if (childFile.isFile()) {
                files.add(childFile);
            }
            //以下几行代码取消注释后可以将所有子文件夹里的文件也获取到列表里
//            else {
//                // 如果是文件夹,则将其内部文件添加进结果集合
//                List cFiles = getAllFile(childFile);
//                if (Objects.isNull(cFiles) || cFiles.isEmpty()) continue;
//                files.addAll(cFiles);
//            }
        }
        return files;
    }

    public static boolean createFilePath(String path){
        try {
            File filePath = new File(path);
            if (!filePath.exists()) {
                if(!filePath.mkdirs()){
                    return false;
                }
            }
        } catch (Exception e) {
            log.error("服务端创建文件夹出错",e);
            return false;
        }
        return true;
    }

    public static boolean deleteFilePath(File file) {
        if (file.isDirectory()) {
            String[] children = file.list();
            if(null != children && children.length > 0){
                File file1 = null;
                //递归删除目录中的子目录下
                for(String str : children){
                    file1 = new File(file, str);
                    log.info(file1.getPath());
                    deleteFilePath(file1);
                }
            }
        }
        return file.delete();
    }

}

导出测试Controller类

package com.web.excel.controller;

import com.util.ZipUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Controller
public class ZipController {

    @RequestMapping("/zip")
    @ResponseBody
    public void zip(HttpServletResponse response, @RequestBody String json) throws Exception {
        try {
            ZipUtil.zipDateFile(response,"E:\\war\\a\\a","test.zip");
        } catch (Exception e){
            log.error("异常了", e);
        }
    }
    
}

ZipController测试类,默认删除压缩原文件。
压缩后,生成的是文件流,前端页面可直接接收。

如需生成在服务器上,只需把 HttpServletResponse 中的 ServletOutputStream 使用 FileOutputStream 替换,即可生成到服务器上。

打包代码:
链接:https://pan.baidu.com/s/1SZ5BC9vpvqRex8DshhhJyw
提取码: snxz

OK,整理到这吧!

如有不正确之处,还望指正!书写不易,觉得有帮助就点个赞吧!☺☺☺

你可能感兴趣的:(工作总结,java,spring,boot,后端)