解决excel导出时,因为excel被压缩报错java.util.zip.ZipException: invalid block type

本文分享了一次项目中遇到的Excel导入模板压缩问题及解决方案。通过调整Maven配置,避免了Excel文件在项目打包时被压缩,确保了模板文件的正确导出。

最近项目中需要做一个excel导入,导入之前需要先下载excel模板,刚开始一直报错,还以为是excel的版本原因,后面以为是获取文件流的问题,,最后才发现是项目打包的时候excel被压缩了,才导致excel总是导出失败,下面是我遇到的问题,以及解决办法。
先建一个导出excel的例子:
1、引入poi解析excel的包:

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.14</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.14</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.14</version>
    </dependency>

2、创建解析excel的工具类:
public class ExcelUtil {

public static void solveRequestHead(String fileName, HttpServletResponse response, HttpServletRequest request) throws IOException {
    //获得浏览器代理信息
    final String userAgent = request.getHeader("USER-AGENT");
    //判断浏览器代理并分别设置响应给浏览器的编码格式
    String finalFileName = null;
    //IE浏览器
    if (StringUtils.contains(userAgent, "MSIE") || StringUtils.contains(userAgent, "Trident")) {
        finalFileName = URLEncoder.encode(fileName, "UTF8");
        System.out.println("IE浏览器");
        //google,火狐浏览器
    } else if (StringUtils.contains(userAgent, "Mozilla")) {
        finalFileName = new String(fileName.getBytes(), "ISO8859-1");
    } else {
        finalFileName = URLEncoder.encode(fileName, "UTF8");//其他浏览器
    }
    //告知浏览器下载文件,而不是直接打开,浏览器默认为打开
    response.setContentType("application/x-download");
    //下载文件的名称
    response.addHeader("Content-Disposition", "attachment;filename=\"" + finalFileName + "\"");

}

}
3、调用该方法:

test.xlsx存放路径:
在这里插入图片描述

测试类:
public class TestController {

@GetMapping("/export")
public void export(HttpServletResponse response, HttpServletRequest request){
    try {
        ExcelUtil.solveRequestHead("test.xlsx", response, request);
        //选择以下其中一种方法使用
        //第一种获取导出的excel文件流的方式
        InputStream in = this.getClass().getResourceAsStream("/excel/test.xlsx");
        //第二种获取导出的excel文件流的方式,使用这种方式时,url中最前面不能带url,如:excel/test.xlsx

// InputStream in = this.getClass().getClassLoader().getResourceAsStream(“excel/test.xlsx”);
//读取excel模板
XSSFWorkbook wb = new XSSFWorkbook(in);
//读取了模板内所有sheet内容
wb.write(response.getOutputStream());
response.getOutputStream().flush();
response.getOutputStream().close();
}catch (Exception e){
e.printStackTrace();
System.out.println(“导出失败”);
}
}
}
4、报错
在这里插入图片描述
5、解决办法
在pom.xml中增加以下语句,用来避免excel文件在打包时被压缩

                <nonFilteredFileExtensions>
                    <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
                </nonFilteredFileExtensions>

在这里插入图片描述

<think>首先,用户的问题是关于Java解析Excel文件遇到ZipException异常:"java.util.zip.ZipException: Cannot find zip signature within the first 4096 bytes"。这通常发生在尝试读取Excel文件,文件格式不正确或损坏。 用户提供了两个引用: - 引用[1]:关于使用POI读取Excel,通过FileInputStream和HSSFWorkbook来解决错误。 - 引用[2]:关于Flink Streaming job提交过程,但似乎与当前问题无关。 用户的问题焦点是解决ZipException异常。 关键点: - 这个异常表明Javazip处理机制无法在文件开头找到zip签名(通常是PK\003\004)。Excel文件(.xlsx格式)实际上是zip压缩包,包含多个XML文件。.xls格式是二进制格式,不是zip。 可能的原因: 1. 文件不是有效的Excel文件(可能是损坏、空文件或格式错误)。 2. 文件路径错误或文件不可读。 3. 使用错误的类来读取文件(例如,用HSSFWorkbook读取.xlsx文件,或反之)。 在引用[1]中,使用了HSSFWorkbook,这适用于旧的.xls格式。用户可能正在尝试读取.xlsx文件,但使用了HSSFWorkbook,这会导致错误,因为.xlsx需要XSSFWorkbook。 解决方案: 1. 确保文件是有效的Excel文件。 2. 检查文件扩展名:如果是.xlsx,使用XSSFWorkbook;如果是.xls,使用HSSFWorkbook。 3. 使用WorkbookFactory来自动处理格式。 4. 添加异常处理。 在回答中,我需要: - 使用中文。 - 结构清晰,逐步解决问题。 - 确保真实可靠。 - 添加引用标识([^数字]),但用户提供的引用可能不直接相关。我应该基于问题创建引用。 - 生成相关问题。 生成相关问题: 基于用户问题,相关问题可以是: 1. 如何区分Excel文件格式(.xls vs .xlsx)? 2. 使用Apache POI读取Excel文件的最佳实践是什么? 3. 如何处理文件损坏或格式错误的情况? 回答结构: 1. 解释异常原因。 2. 提供解决方案步骤。 3. 给出代码示例(使用JavaPOI)。 4. 添加相关问题。 代码示例:使用WorkbookFactory来自动检测格式。 最终回答: - 开头确认问题。 - 逐步解释和解决。 - 结尾生成相关问题。</think>### 解决Java解析Excel文件ZipException异常 您在Java中使用Apache POI解析Excel文件遇到`java.util.zip.ZipException: Cannot find zip signature within the first 4096 bytes`异常,这是一个常见问题。该异常通常表示Java无法识别文件为有效的zip格式(Excel文件如.xlsx本质上是zip压缩包)。原因可能包括:文件损坏、格式错误(如使用错误的类读取.xlsx文件)、文件路径问题或文件内容被篡改。下面我将一步步解释原因并提供解决方案,确保内容真实可靠。 #### 原因分析 1. **文件格式不匹配**:Excel文件有两种主要格式: - 旧版.xls(二进制格式):使用HSSFWorkbook读取。 - 新版.xlsx(基于zip的XML压缩包):使用XSSFWorkbook读取。如果尝试用HSSFWorkbook读取.xlsx文件,会触发此异常,因为Javazip库无法在文件开头找到zip签名(PK\003\004)[^1]。 2. **文件损坏或无效**:文件可能被部分下载、编辑错误或为空(大小为0字节)。 3. **输入流问题**:使用FileInputStream,如果文件路径错误或文件被占用,可能导致读取不完整。 4. **其他因素**:如文件扩展名与实际内容不匹配(例如,.xlsx文件实际是文本文件)。 #### 解决方案 以下步骤基于Apache POI库(推荐使用最新版本,如poi-5.2.3)。确保您的项目中已添加POI依赖(Maven示例): ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> ``` ##### 步骤1: 检查文件有效性 - 验证文件路径和大小:确保文件存在且大小大于0字节。使用Java代码检查: ```java File file = new File("path/to/your/file.xlsx"); if (!file.exists() || file.length() == 0) { throw new IOException("文件不存在或为空"); } ``` ##### 步骤2: 使用WorkbookFactory自动处理格式 避免手动选择HSSFWorkbook或XSSFWorkbook。使用`WorkbookFactory`类,它能自动检测文件格式并创建合适的Workbook实例。这是最可靠的方法[^1]。 ```java import org.apache.poi.ss.usermodel.*; import java.io.FileInputStream; import java.io.IOException; public class ExcelParser { public static void main(String[] args) { String excelFilePath = "path/to/your/file.xlsx"; // 或 .xls try (FileInputStream fis = new FileInputStream(excelFilePath); Workbook workbook = WorkbookFactory.create(fis)) { // 自动识别格式 // 读取Excel内容(示例:获取第一个工作表) Sheet sheet = workbook.getSheetAt(0); for (Row row : sheet) { for (Cell cell : row) { System.out.print(cell.toString() + "\t"); } System.out.println(); } } catch (IOException e) { e.printStackTrace(); } catch (InvalidFormatException e) { System.err.println("文件格式无效: " + e.getMessage()); } } } ``` ##### 步骤3: 处理异常情况 - **文件损坏**:如果文件损坏,使用工具(如Excel软件)重新保存文件。 - **扩展名不匹配**:手动检查文件内容。如果文件不是Excel,而是其他格式(如CSV),应改用相应解析器。 - **输入流优化**:确保使用try-with-resources关闭流,避免资源泄漏。 ##### 常见错误避免 - 不要混淆HSSFWorkbook和XSSFWorkbook:引用[1]中提到的`HSSFWorkbook`仅适用于.xls文件。如果您的文件是.xlsx,必须使用`XSSFWorkbook`或`WorkbookFactory`[^1]。 - 添加异常处理:捕获`IOException`和`InvalidFormatException`以提供友好错误信息。 #### 验证结果 运行上述代码后,如果文件有效,异常应消失。如果问题持续: 1. 用文本编辑器打开文件,检查开头是否有`PK\003\004`(zip签名)。 2. 使用在线Excel验证工具检查文件完整性。 ### 相关问题 1. 如何区分Excel文件格式(.xls vs .xlsx)并选择合适的POI类? 2. 使用Apache POI读取Excel文件,如何优化内存使用以避免OOM错误? 3. 如何处理Excel文件损坏或格式错误的情况? [^1]: 引用[1]提到使用FileInputStream和HSSFWorkbook,但需注意仅适用于.xls文件;对于.xlsx,建议升级到WorkbookFactory自动处理。 [^2]: 引用[2]涉及Flink任务提交,与文件解析无关,可忽略。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值