You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取Zip包内XLSX文件时出现Zip签名错误的解决求助

问题分析

你遇到的ZipException: Cannot find zip signature within the first 4096 bytes错误,核心原因是:当你通过zipInputStream.getNextEntry()定位到XLSX条目后,当前的zipInputStream指针已经指向了该条目的内容起始位置,而XLSX本身就是一种Zip格式文件,XSSFWorkbook会尝试把传入的流当作完整的Zip包解析,但此时流的开头并不是Zip包的签名(而是XLSX条目内容的开头),所以报错找不到Zip签名。

解决方案

需要将ZipEntry对应的XLSX内容完整读取到一个独立的输入流中,再传给XSSFWorkbook。推荐使用ByteArrayInputStream来包裹读取到的字节数据,确保XSSFWorkbook拿到的是完整的、从头开始的XLSX内容流。

同时,建议用try-with-resources语法自动管理流和Workbook的资源,避免手动关闭遗漏导致的泄漏。

修正后的代码示例:

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

// 导入Apache Commons IO的IOUtils,或者自己实现字节读取逻辑
import org.apache.commons.io.IOUtils;

for(MultipartFile file : files) {
    if (Objects.requireNonNull(file.getContentType()).contains("application/x-zip-compressed")) {
        try (InputStream fileInputStream = file.getInputStream();
             ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {

            ZipEntry entry;
            while ((entry = zipInputStream.getNextEntry()) != null) {
                if (entry.getName().endsWith(".xlsx") && !entry.isDirectory()) {
                    // 将当前ZipEntry的内容读取为字节数组
                    byte[] xlsxBytes = IOUtils.toByteArray(zipInputStream);
                    // 用ByteArrayInputStream包裹,确保流从头开始
                    try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(xlsxBytes);
                         XSSFWorkbook newWorkbook = new XSSFWorkbook(byteArrayInputStream)) {

                        Sheet newSheet = newWorkbook.getSheetAt(0);
                        // 在这里读取Sheet内容
                        // ...
                    }
                }
                // 关闭当前ZipEntry
                zipInputStream.closeEntry();
            }
        } catch (IOException e) {
            // 处理IO异常
            e.printStackTrace();
        }
    }
}
关键注意事项
  • 必须跳过Zip中的目录条目:添加!entry.isDirectory()判断,避免尝试读取目录内容导致错误。
  • 不要直接复用ZipInputStream给XSSFWorkbook:ZipInputStream在定位到条目后,指针已经移动,无法满足XSSFWorkbook对完整Zip流的要求。
  • 依赖Apache Commons IO简化字节读取:如果不想引入该依赖,可以手动实现字节读取逻辑(比如用ByteArrayOutputStream循环读取字节)。

内容的提问来源于stack exchange,提问作者chaunv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:10:02