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

二 : 需要实现的效果

原文件
在这里插入图片描述
生成文件
在这里插入图片描述
压缩后,是否删除,可通过参数控制。

三 : 导出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<File> 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,整理到这吧!

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

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中可以使用ZipOutputStream类将多个txt文件打包成一个zip文件。以下是一个简单的示例代码,可以将List中的每个元素导出到单独的txt文件中,并将这些txt文件打包成一个zip文件: ```java import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ExportListToZip { public static void main(String[] args) { List<String> dataList = new ArrayList<>(); // 定义要导出的List集合 dataList.add("This is the first line."); dataList.add("This is the second line."); dataList.add("This is the third line."); String zipFileName = "data.zip"; // 定义要导出zip文件名 try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFileName))) { for (int i = 0; i < dataList.size(); i++) { String fileName = "file" + (i + 1) + ".txt"; // 定义要导出文件名 String data = dataList.get(i); // 获取要导出的数据 BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); writer.write(data); // 写入文件内容 writer.close(); // 关闭文件流 FileInputStream fileIn = new FileInputStream(fileName); ZipEntry zipEntry = new ZipEntry(fileName); zipOut.putNextEntry(zipEntry); // 将文件添加到zip输出流中 byte[] bytes = new byte[1024]; int length; while ((length = fileIn.read(bytes)) >= 0) { zipOut.write(bytes, 0, length); // 将文件数据写入zip输出流中 } fileIn.close(); // 关闭文件流 System.out.println("File " + fileName + " exported successfully!"); } } catch (IOException e) { e.printStackTrace(); } } } ``` 在上面的代码中,我们定义了一个List集合,并向其中添加了三个元素。然后定义了一个要导出zip文件名。接着,使用ZipOutputStream类创建一个新的zip文件,并使用for循环遍历List中的每个元素,生成一个文件名和要导出的数据。然后使用BufferedWriter类和FileWriter类创建一个新的文件,并将数据写入文件中。接着,使用FileInputStream类将文件数据读取出来,并使用ZipEntry类将文件添加到zip输出流中。最后,关闭文件流并输出一条消息表示文件已成功导出zip文件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

message丶小和尚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值