Java代码如何对Excel文件进行zip压缩

1:新建 ZipUtils 工具类

java 复制代码
package com.ly.cloud.datacollection.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ZipUtils {
	private static final int BUFFER_SIZE = 10 * 1024;

   /**
    * 
    * @param fileList 多文件列表
    * @param zipPath 压缩文件临时目录
    * @return
    */
    public static Boolean zipFiles(List<File> fileList, File zipPath) {
    	boolean flag = true;
        // 1 文件压缩
        if (!zipPath.exists()) { // 判断压缩后的文件存在不,不存在则创建
            try {
                zipPath.createNewFile();
            } catch (IOException e) {
            	flag=false;
                e.printStackTrace();
            }
        }
        FileOutputStream fileOutputStream=null;
        ZipOutputStream zipOutputStream=null;
        FileInputStream fileInputStream=null;
        try {
            fileOutputStream=new FileOutputStream(zipPath); // 实例化 FileOutputStream对象
            zipOutputStream=new ZipOutputStream(fileOutputStream); // 实例化 ZipOutputStream对象
            ZipEntry zipEntry=null; // 创建 ZipEntry对象
            for (int i=0; i<fileList.size(); i++) { // 遍历源文件数组
                fileInputStream = new FileInputStream(fileList.get(i)); // 将源文件数组中的当前文件读入FileInputStream流中
                zipEntry = new ZipEntry("("+i+")"+fileList.get(i).getName()); // 实例化ZipEntry对象,源文件数组中的当前文件
                zipOutputStream.putNextEntry(zipEntry);
                int len; // 该变量记录每次真正读的字节个数
                byte[] buffer=new byte[BUFFER_SIZE]; // 定义每次读取的字节数组
                while ((len=fileInputStream.read(buffer)) != -1) {
                    zipOutputStream.write(buffer, 0, len);
                }
            }
            zipOutputStream.closeEntry();
            zipOutputStream.close();
            fileInputStream.close();
            fileOutputStream.close();

        } catch (IOException e) {
        	flag=false;
            e.printStackTrace();
        } finally {
            try {  
            	fileInputStream.close();
            	zipOutputStream.close();
            	fileOutputStream.close();
            } catch (Exception e){
            	flag=false;
                e.printStackTrace();
            }
        }
		return flag;
    }
   

    /**
     * @param srcDir           压缩文件夹路径
     * @param keepDirStructure 是否保留原来的目录结构,
     *                         true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @param response 
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip(String[] srcDir, String outDir,
                             boolean keepDirStructure, HttpServletResponse response) throws RuntimeException, Exception {
        // 设置输出的格式
        response.reset();
        response.setContentType("bin");
        outDir = URLEncoder.encode(outDir,"UTF-8");
        response.addHeader("Content-Disposition","attachment;filename=" + outDir);
        OutputStream out = response.getOutputStream();
        response.setContentType("application/octet-stream");
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(out);
            List<File> sourceFileList = new ArrayList<File>();
            for (String dir : srcDir) {
                File sourceFile = new File(dir);
                sourceFileList.add(sourceFile);
            }
            compress(sourceFileList, zos, keepDirStructure);
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } 
       finally {
        	if (zos != null) {
        		try {
        			zos.close();
        			out.close();
        		} catch (IOException e) {
        			e.printStackTrace();
        		}
        	}
		}
    }
    /**
     * @param srcDir           压缩文件夹路径
     * @param keepDirStructure 是否保留原来的目录结构,
     *                         true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @param response 
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip(String[] srcDir, String outDir,
                             boolean keepDirStructure) throws RuntimeException, Exception {
        // 设置输出的格式
        //outDir = URLEncoder.encode(outDir,"UTF-8");
    	long start= System.currentTimeMillis();
        FileOutputStream out=null;
        ZipOutputStream zos = null;
        try {
        	out=new FileOutputStream(outDir); // 实例化 FileOutputStream对象
            zos = new ZipOutputStream(out);
            List<File> sourceFileList = new ArrayList<File>();
            for (String dir : srcDir) {
                File sourceFile = new File(dir);
                sourceFileList.add(sourceFile);
            }
            compress(sourceFileList, zos, keepDirStructure);
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } 
       finally {
        	if (zos != null) {
        		try {
        			zos.close();
        			out.close();
        			log.info(outDir+"压缩完成");
        			printInfo(start);
        		} catch (IOException e) {
        			e.printStackTrace();
        		}
        	}
		}
    }

    /**
     * 递归压缩方法
     *
     * @param sourceFile       源文件
     * @param zos              zip输出流
     * @param name             压缩后的名称
     * @param keepDirStructure 是否保留原来的目录结构,
     *                         true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception 异常
     */
    private static void compress(File sourceFile, ZipOutputStream zos,
                                 String name, boolean keepDirStructure) throws Exception {
        byte[] buf = new byte[BUFFER_SIZE];
        recursion(sourceFile, zos, name, keepDirStructure, buf);
    }

    /**
     *
     * @param sourceFileList    源文件列表
     * @param zos               zip输出流
     * @param keepDirStructure  是否保留原来的目录结构,
     *                          true:保留目录结构;
     *                          false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception        异常
     */
    private static void compress(List<File> sourceFileList,
                                 ZipOutputStream zos, boolean keepDirStructure) throws Exception {
        byte[] buf = new byte[BUFFER_SIZE];
        for (File sourceFile : sourceFileList) {
            String name = sourceFile.getName();
            recursion(sourceFile, zos, name, keepDirStructure, buf);
        }
    }

    /**
     *
     * @param sourceFile       源文件
     * @param zos              zip输出流
     * @param name             文件名
     * @param keepDirStructure 否保留原来的目录结构,
     *                         true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @param buf              字节数组
     * @throws Exception       异常
     */
    private static void recursion(File sourceFile, ZipOutputStream zos, String name, boolean keepDirStructure, byte[] buf) {
        if (sourceFile.isFile()) {
        	FileInputStream in=null;
            try {
            	in = new FileInputStream(sourceFile);
				zos.putNextEntry(new ZipEntry(name));
				int len;
				while ((len = in.read(buf)) != -1) {
					zos.write(buf, 0, len);
				}
				zos.closeEntry();
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                if (keepDirStructure) {
                    try {
						zos.putNextEntry(new ZipEntry(name + "/"));
						zos.closeEntry();
					} catch (IOException e) {
						e.printStackTrace();
					}
                }
            } else {
                for (File file : listFiles) {
                    if (keepDirStructure) {
                        try {
							compress(file, zos, name + "/" + file.getName(),
							        true);
						} catch (Exception e) {
							e.printStackTrace();
						}
                    } else {
                        try {
							compress(file, zos, file.getName(), false);
						} catch (Exception e) {
							e.printStackTrace();
						}
                    }
                }
            }
        }
    }
    public static int deleteFile(File file) {
        //判断是否存在此文件
    	int count=0;
        if (file.exists()) {
            //判断是否是文件夹
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                //判断文件夹里是否有文件
                if (files.length >= 1) {
                    //遍历文件夹里所有子文件
                    for (File file1 : files) {
                        //是文件,直接删除
                        if (file1.isFile()) {
                        	count++;
                            file1.delete();
                        } else {
                            //是文件夹,递归
                        	count++;
                        	deleteFile(file1);
                        }
                    }
                    //file此时已经是空文件夹
                    file.delete();
                } else {
                    //是空文件夹,直接删除
                    file.delete();
                }
            } else {
                //是文件,直接删除
                file.delete();
            }
        } else {
        }
		return count;
    }
    

public static void downloadFile(String path, File file, String outDir, HttpServletResponse response){
        OutputStream os = null;
        FileInputStream fis=null;
        try {
        	fis = new FileInputStream(file);
            // 取得输出流
            os = response.getOutputStream();
            //String contentType = Files.probeContentType(Paths.get(file.getAbsolutePath()));
            outDir = URLEncoder.encode(outDir,"UTF-8");
            response.addHeader("Content-Disposition","attachment;filename=" + outDir);
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Length", String.valueOf(file.length()));
            //response.setHeader("Content-Disposition", "attachment;filename="+ outDir);
            //response.setHeader("Content-Disposition", "attachment;filename="+ new String(file.getName().getBytes("utf-8"),"ISO8859-1"));
			/*
			 * int len; // 该变量记录每次真正读的字节个数 byte[] buffer=new byte[BUFFER_SIZE]; //
			 * 定义每次读取的字节数组 while ((len=fis.read(buffer)) != -1) { os.write(buffer, 0, len);
			 * }
			 */
            
            WritableByteChannel writableByteChannel = Channels.newChannel(os);
            FileChannel fileChannel = fis.getChannel();
            	ByteBuffer buffer=ByteBuffer.allocate(BUFFER_SIZE);
            	long total=0L;
            	int len=0;
				while((len=fileChannel.read(buffer))!=-1){
					total=total+len;
						buffer.flip();
						// 保证缓冲区的数据全部写入
						   while (buffer.hasRemaining())
				            {
							   writableByteChannel.write(buffer);
				            }
						buffer.clear();
            	}
            log.info(outDir+"下载完成");
            os.flush();
            fileChannel.close();
            writableByteChannel.close();
        } catch (IOException e) {
           e.printStackTrace();
        }
        //文件的关闭放在finally中
        finally {
            try {
            	 if (fis != null) {
            		 fis.close();
                 }
            	 if (os != null) {
             		os.flush();
             		os.close();
             	}
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

}



public static void printInfo(long beginTime) {
	long endTime = System.currentTimeMillis();
	long total = endTime - beginTime;
	log.info("压缩耗时:" + total / 1000 + "秒");

}
}
 

2:简单测试

java 复制代码
    @GetMapping(value = "/zip")
    @AnonymityAnnotation(access = true)
    public WebResponse<String> zip(@RequestParam("file") MultipartFile file) throws IOException {
        InputStream stream = file.getInputStream();
        System.out.println(stream);
        //下载压缩后的地址
        String path = "D:/91-69ddf076d28040d29e59aec22b65b150";
        //获取文件原本的名称
        String fileName = file.getOriginalFilename();
        System.out.println(fileName);
        String[] src = { path + "/" + fileName };
        String outDir = path + "/69.zip";
        try {
            ZipUtils.toZip(src, outDir, true);
        } catch (Exception e) {
        }
        return new WebResponse<String>().success("OK");
    }

3:效果图

相关推荐
E-iceblue2 天前
Excel 列转行/行列转换全指南:从 4 种常见解法到 Python 批量自动化
python·excel·python库·spire.xls
Data-Miner2 天前
AI处理数据的脚本复用与逻辑复用有什么区别?哪种方式更能沉淀工作成果
数据分析·excel
福兮说2 天前
在浏览器里写一个“够用就好“的 Excel 公式求值器
前端·javascript·excel·编译原理
慧都小妮子3 天前
标签打印如何减少手工抄数?用Bartender 直连 Excel 批量打印
excel·bartender·条码打印·标签打印软件·数据驱动打印·工业打印机
SunnyDays10113 天前
Java 设置 Excel 数据验证:整数、日期、文本长度、下拉列表和时间
java·excel·数据验证·下拉列表
Metaphor6923 天前
使用 Python 设置 Excel 行列自适应 【代码示例】
python·excel
用户0332126663674 天前
使用 Python 设置 Excel 行列自适应 【代码示例】
python·excel
企业数字化笔记4 天前
固定资产Excel批量导入怎么防重复?资产编码、重复检查和错误回执
java·后端·excel
CORNERSTONE3654 天前
低代码开发有哪些应用场景?
低代码·excel·erp·mes·企业数字化
小葱炖豆腐5 天前
python绘制excel折线图
python·excel·numpy·pandas·matplotlib