Java用POI读取excel文件,报异常:NotOLE2FileException: Invalid header signature; read xxx, expected 0xE11AB1A1

这几天在开发时遇到了极其坑爹的问题。开发的主要功能是在导出某些订单数据至Excel,因为自己一个一个去写表头这种操作代码耦合性实在太强,到时想要修改表头格式又需要回到去代码中修改,所以这是一种很愚蠢的零分操作!那么在这里就用到了POI的Excel模版功能(POI是apache提供给java对office进行读写操作的库,也是前些天开发时才了解到)。模版作为一种资源文件就被我存放在聚合工程的某一module的/src/main/resources/exportconfig 目录下:

那么,具体问题是啥呢?就是我标题中说到的异常:

NotOLE2FileException: Invalid header signature; read 0xE011BDBFEFBDBFEF, expected 0xE11AB1A1E011CFD0

我也是第一次遇到如此神奇的异常呀!那么它究竟是个什么意思?经过相关搜索后发现是当POI在进行模板文件加载后,发现这个文件的格式不是标准的excel文件(.xls或者.xlsx),这个文件的格式不是excel,那么POI当然也就没办法打开了!

诸如stackoverflow这样的网站也有不少人贴出了这样的问题,上面给出的回复是我看到的excel文件仅仅是“看起来是”,事实上这可能是一个破损的或者是一个后缀强行加上了“xls”的其他格式的文件,所以很多热心网友给出的解决方案是通过excel打开这个文件,然后将文件“另存为”xls格式。在我满怀希望地经过多次这样的操作后,我发现这根本没有一点卵用(事实上,我发现无论是excel还是mac的numbers都可以很顺利地打开文件)。所以我隐隐觉得不应该是模板本身的格式问题。经过了多次奇奇怪怪的操作后,结果很显然是令我绝望的。当然,这些失败的经验也给我了一点启发:

会不会是工程在部署时格式被破坏了呢??学长大佬的一句话让我有一种茅塞顿开之感:工程在部署时是打成war包的,那么是不是在打包的时候出了问题?

于是我在本地将工程打成war包,命令如下:

mvn package -Dmaven.test.skip

在打包后,找到excel模板所在的jar包,解压后,打开,惊人地发现格式已经被破坏了!!


(这里出于隐私,就不贴出原本的模板文件了)

那么会是什么问题呢?但是可以肯定的是maven打包的时候出了问题!在经过相关查看后,发现pom文件中有这么一段<build> </build>下的依赖:

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
</resources>

这段依赖是什么意思呢?通过这段依赖可以根据不同的环境(测试、预发、线上等环境)来过滤项目中的属性资源配置。到了这里,我大概也知道了就是因为这段依赖导致打包时excel文件被修改了。当问题可以被具像化时,我认为离成功就不远了!于是我就满怀激情地去调bug了!

首先我想到,那么可不可以直接将filtering改成false呢?结果很明显是不可以的——当不对属性资源进行过滤替换时,会出现spring无法读取某个变量的情况!

既然这个方案不行,那么接下来又尝试其他的方案:filtering下配置<exclude> </exclude>,根据网上其他的解决方案,配置了<exclude></exclude>之后这个问题也没有被解决,当时我的心态都快奔了 - -

接着我又准备在maven的打包插件下配置<nonFilteredFileExtensions> </nonFilteredFileExtensions>,顾名思义就是不被过滤的文件后缀:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <webResources>
            <resource>
                <!-- 元配置文件的目录,相对于pom.xml文件的路径 -->
                <directory>src/main/webapp/WEB-INF</directory>
                <!-- 目标路径 -->
                <targetPath>WEB-INF</targetPath>
                <filtering>true</filtering>
            </resource>
        </webResources>
        <nonFilteredFileExtensions>
            <nonFilteredFileExtension>xls</nonFilteredFileExtension>
            <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
    </configuration>
</plugin>

这样的解决方案理应没什么毛病啊!那么为什么不对呢!为什么呢!为什么要对我这么残忍!然而我会放弃么?!不存在的,我这样身残志坚的选手人生字典中没有屈服这一说!于是,我尝试添加一个maven的插件,试图在maven打包时可以放过我的excel文件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <encoding>UTF-8</encoding>
        <nonFilteredFileExtensions>
            <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
            <nonFilteredFileExtension>xls</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
    </configuration>
</plugin>

然后!问题就被解决了!通过maven本地打包后的excel模板文件正常了!

喜大普奔,撒花庆祝!

over~~~

  • 19
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
Java使用POI库可以实现对Excel文件读取操作。具体的步骤如下: 1. 引用POI库。在Java项目中引入POI相关的jar包。 2. 创建文件输入流。使用FileInputStream类创建一个输入流对象,并指定要读取Excel文件路径。 3. 创建工作簿对象。使用HSSFWorkbook类创建一个工作簿对象,将输入流作为参数传入。 4. 获取工作表。使用getSheetAt方法获取指定的工作表,可以通过工作表的索引或名称进行获取。 5. 获取行。使用getRow方法获取指定行的对象,行号作为参数传递给该方法。 6. 获取单元格。使用getCell方法获取指定单元格的对象,行号和列号作为参数传递给该方法。 7. 获取单元格的值。使用getStringCellValue方法获取单元格的值,将其赋给一个字符串变量。 8. 输出结果。使用System.out.println方法将获取到的数据打印出来。 需要注意的是,在读取Excel文件时可能会出现FileNotFoundException和IOException异常,需要进行异常处理。同时,在读取完成后,需要关闭输入流。 下面是一个示例代码,用于演示Java使用POI读取Excel文件: ```java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; public class ExcelReader { public static void poiRead() { FileInputStream xlsStream = null; try { // 创建文件输入流 xlsStream = new FileInputStream(new File("C:\\Users\\itour\\Desktop\\poiTest.xls")); // 创建工作簿对象 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(xlsStream); // 获取工作表 HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0); // 获取行 HSSFRow row = sheetAt.getRow(0); // 获取单元格 HSSFCell cell = row.getCell(0); // 获取单元格的值 String cellValue = cell.getStringCellValue(); System.out.println("获取到的数据是:" + cellValue); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (xlsStream != null) { try { xlsStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } } ``` 以上代码演示了如何使用POI读取Excel文件中第一个工作表的第一个单元格的值。你可以根据自己的需求进行修改和扩展。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值