【问题解决】apache.poi 3.1.4版本升级到 5.2.3,导出文件报错版本无法解析

【问题解决】apache.poi 3.1.4版本升级到 5.2.3,导出文件报错无法解析

3.1.4版本代码:

bash 复制代码
    /**
     * 创建workbook
     * @param inp
     * @return
     * @throws Exception
     */
    public Workbook createworkbook(InputStream inp) throws Exception {


        if (!inp.markSupported()) {
            inp = new PushbackInputStream(inp, 8);
        }

        if (POIFSFileSystem.hasPOIFSHeader(inp)) {
            return new HSSFWorkbook(inp);
        }
        if (POIXMLDocument.hasOOXMLHeader(inp)) {
            return new XSSFWorkbook(OPCPackage.open(inp));
        }
        throw new IllegalArgumentException("你的excel版本目前poi解析不了");
    }

在POI 4.0.x版本过后,POIFSFileSystem.hasPOIFSHeader()与 POIXMLDocument.hasOOXMLHeader()便弃用了,所以我们需要找到新版本的替代方法,为此查阅了不少资料。

这里有两个方案可以参考一下:

java 复制代码
public Workbook createworkbook(InputStream inp) throws Exception {
    try (PushbackInputStream pushbackInputStream = new PushbackInputStream(inp, 8)) {
        byte[] header = new byte[8];
        int read = pushbackInputStream.read(header);
        pushbackInputStream.unread(header, 0, read);

        if (POIUtils.hasOOXMLHeader(header)) {
            return new XSSFWorkbook(OPCPackage.open(pushbackInputStream));
        } else if (POIUtils.hasPOIFSHeader(header)) {
            return new HSSFWorkbook(pushbackInputStream);
        } else {
            throw new IllegalArgumentException("不支持的 Excel 格式");
        }
    }
}

主要变更如下:

  1. 使用 POIUtils.hasOOXMLHeader(header) 方法替换 POIDataSamples.getSpreadSheetInstance().acceptsFile(header) 方法。这个方法可以检测 XSSF 格式(OOXML)。
  2. 使用 POIUtils.hasPOIFSHeader(header) 方法检测 HSSF 格式(97-2003 Excel)。
  3. 如果以上两种方式都无法识别,则抛出一个自定义的异常。

这种方式可以有效地替换之前的代码,并适用于 Apache POI 5.2.3 版本。

需要注意的是,需要引入 org.apache.poi.util.POIUtils 类,这个类是 Apache POI 5.2.3 中新增的一个工具类,提供了一些常用的工具方法。
2.

java 复制代码
public Workbook createworkbook(InputStream inp) throws Exception {
    try (PushbackInputStream pushbackInputStream = new PushbackInputStream(inp, 8)) {
        byte[] header = new byte[8];
        int read = pushbackInputStream.read(header);
        pushbackInputStream.unread(header, 0, read);

        if (isXSSF(header)) {
            return new XSSFWorkbook(OPCPackage.open(pushbackInputStream));
        } else if (isHSSF(header)) {
            return new HSSFWorkbook(pushbackInputStream);
        } else {
            throw new IllegalArgumentException("不支持的 Excel 格式");
        }
    }
}

private boolean isXSSF(byte[] header) {
    // 检查 OOXML 文件头标识
    return header[0] == (byte) 0x50 && header[1] == (byte) 0x4B && header[2] == (byte) 0x03 && header[3] == (byte) 0x04;
}

private boolean isHSSF(byte[] header) {
    // 检查 POIFS 文件头标识
    return header[0] == (byte) 0xD0 && header[1] == (byte) 0xCF && header[2] == (byte) 0x11 && header[3] == (byte) 0xE0;
}	

这个替代方案中,自己实现了 isXSSF 和 isHSSF 方法来检测 OOXML 和 POIFS 文件头标识,达到了同样的效果。

踩坑啊!

相关推荐
云和数据.ChenGuang8 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠8 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
silvamux_10 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
步行cgn11 小时前
StringHttpMessageConverter 详解:Spring MVC 中字符串读写的默认转换器
java·spring·mvc
摇滚侠11 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 11
java·笔记·python
小蒜学长11 小时前
基于Spring Boot+Vue3的在线医疗咨询系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·在线问诊·在线医疗咨询系统
Deng桑11 小时前
SpringAI写第一个Agent-把工单循环跑起来
java·agent·工具调用·spring ai
步行cgn13 小时前
@ResponseBody 详解:Spring MVC 中把返回值直接写入响应体
java·spring·mvc
jason成都14 小时前
RTKLIB 的 Java 移植版来了:rtklib-java v3.3.0 功能全景
java·gnss·rtklib·rtklib_java
LazyHunter914 小时前
JDK 28:Java 下一步方向解析与新特性展望
java·jdk