poi读取excel报错Your InputStream was neither an OLE2 stream, nor an OOXML stream

2年前 (2022) 程序员胖胖胖虎阿
234 0 0

当 java 使用 poi 读取后缀是 xls 的 excel 类型文件时报错:

Your InputStream was neither an OLE2 stream, nor an OOXML stream

报错的代码:

Workbook wb = WorkbookFactory.create(is);

点进 create 方法里看下poi的源码:

public static Workbook create(InputStream inp) throws IOException, InvalidFormatException {
        if (!((InputStream)inp).markSupported()) {
            inp = new PushbackInputStream((InputStream)inp, 8);
        }

        if (POIFSFileSystem.hasPOIFSHeader((InputStream)inp)) {
            return new HSSFWorkbook((InputStream)inp);
        } else if (POIXMLDocument.hasOOXMLHeader((InputStream)inp)) {
            return new XSSFWorkbook(OPCPackage.open((InputStream)inp));
        } else {
            throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
        }
    }

两个 if 中的 hasPOIFSHeade 和 hasOOXMLHeader 是去读取 excel 文件流的前8 byte 判断文件信息,如果不是excel类型文件或者不是二进制类型文件直接就抛出异常"Your InputStream was neither an OLE2 stream, nor an OOXML stream"

分析:

使用 Sublime Text 文本编辑器或者 Notepad++ 打开有问题的 xls 文件如下,是文本形式的xml:
poi读取excel报错Your InputStream was neither an OLE2 stream, nor an OOXML stream

而使用 Sublime Text 文本编辑器打开其他正常的 xls 文件如下,是二进制:
poi读取excel报错Your InputStream was neither an OLE2 stream, nor an OOXML stream

问题的原因:

有问题的 xls 文件其实是 Office OpenXml 类型的文件也叫做SpreadSheetML格式(Excel的xml格式),它的后缀本应该是xml,而不应该是xls,它不是标准的 excel 文件,所以使用poi读取就报错了。

解决方式一:

使用excel打开有问题的 xls 文件,如下:
选择是,然后文件另存为xls格式,再使用 poi 解析就不会报错了
poi读取excel报错Your InputStream was neither an OLE2 stream, nor an OOXML stream

解决方式二:

通过java代码把Office OpenXml 类型的文件转化为excel。

1.通过下面任意一种方式下载spire.xls.jar

  • 官网下载jar

  • 百度云下载 链接:https://pan.baidu.com/s/1wfna9JysI68ll_kbfUgRkA 提取码:bzhs

  • 通过Maven下载,Maven的 pom.xml 中配置的存储库和依赖下载如下:

    <repositories>
            <repository>
                <id>com.e-iceblue</id>
                <name>e-iceblue</name>
                <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
            </repository>
    </repositories>
    
    <dependencies>
        <dependency>
            <groupId> e-iceblue </groupId>
            <artifactId>spire.xls</artifactId>
            <version>5.3.3</version>
        </dependency>
    </dependencies>
    

2.转换为excel 代码如下

import com.spire.xls.FileFormat;
import com.spire.xls.Workbook;

public class MainServer {
    public static void main(String[] args) {
        //加载xml文件或 Office OpenXml 类型的xsl文件
        Workbook wb = new Workbook();
        wb.loadFromXml("F:\\test.xml");

        //转为2013版xlsx格式的Excel
        wb.saveToFile("F:\\newExcel.xlsx", FileFormat.Version2013);
    }
}

相关文章

暂无评论

暂无评论...