通过apache poi读取excel文件(在classpath中)

时间:2014-12-09 19:38:28

标签: java excel maven apache-poi classpath

我正在尝试阅读(使用apache poi).xlsx文件,该文件不在文件系统中,而是在classpath中。我正在使用maven - 所以它在资源文件夹中。

我的代码是 -

InputStream resourceAsStream = MyReader.class.getClassLoader().getResourceAsStream("test.xlsx");
   Workbook wb = new XSSFWorkbook(resourceAsStream);

我得到了这个例外。

Caused by: java.lang.IllegalArgumentException: MALFORMED
        at java.util.zip.ZipCoder.toString(ZipCoder.java:58) ~[?:1.7.0_51]
        at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:297) ~[?:1.7.0_51]
        at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:121) ~[?:1.7.0_51]
        at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.<init>(ZipInputStreamZipEntrySource.java:51) ~[poi
a3]
        at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:88) ~[poi-ooxml-3.11-beta3.jar:3.11-beta3]
        at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:272) ~[poi-ooxml-3.11-beta3.jar:3.11-beta3]
        at org.apache.poi.util.PackageHelper.open(PackageHelper.java:37) ~[poi-ooxml-3.11-beta3.jar:3.11-beta3]

当我从文件系统中读取同一文件时,一切都很好。 我的代码中是否有错误或者我错过了什么?

UPDATE1:这是在Web应用程序中,因此代码部署在tomcat 7中。

UPDATE2:当我以这种方式阅读同一个文件时 - 它有效。

File file = new File("C:\\Users\\.....\\test.xlsx");
 FileInputStream fileInputStream = new FileInputStream(file);

 Workbook wb = new XSSFWorkbook(fileInputStream);

感谢

3 个答案:

答案 0 :(得分:7)

在这个问题上花了好几天后,我在stackoverflow中找到了答案))。 FileInputStream vs ClassPathResource vs getResourceAsStream and file integrity

maven-resources-plugin过滤中的问题,它会破坏excel文件。

You should not filter binary files like excel and use two mutually exclusive resource sets as described at the bottom of this page 

maven resources plugin

答案 1 :(得分:1)

向@ user1321466回答添加更多信息,过滤你可以按照maven resources plugin site中的说明进行操作:

  

如果您同时拥有文本文件和二进制文件作为资源   建议有两个单独的文件夹。一个文件夹   src / main / resources(默认值)表示未过滤的资源   和另一个文件夹src / main / resources-filtered为资源   过滤了。

或只是从过滤中排除文件:

<resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    <excludes>
        <exclude>**/*.xsd</exclude>
        <exclude>**/*.xml</exclude>
    </excludes>
</resource>
<resource>
    <directory>src/main/resources</directory>
    <filtering>false</filtering>
    <includes>
        <include>**/*.xsl</include>
        <include>**/*.xslx</include>
    </includes>
</resource>

答案 2 :(得分:0)

该文件是否位于类路径的顶部,即在WEB-INF / classes中?

Classloader.getResource()的API文档说资源名称为:

&#34;资源的名称是标识资源的&#39; /&#39; - 分隔的路径名。&#34;

因此,如果您的文件位于某个子目录中,则该路径应该是资源名称的一部分。