这几天在开发时遇到了极其坑爹的问题。开发的主要功能是在导出某些订单数据至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~~~