I am trying to read (using apache poi) .xlsx file which is not in file system but in classpath. I am using maven - so it is in resources folder.
my code is -
InputStream resourceAsStream = MyReader.class.getClassLoader().getResourceAsStream("test.xlsx");
Workbook wb = new XSSFWorkbook(resourceAsStream);
I am getting this exception.
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]
When I read same file from file system everything is fine. Is there a bug in my code or do I miss understand something?
UPDATE1: This is in web app, so code is deployed in tomcat 7.
UPDATE2: when I read same file in this way - it works.
File file = new File("C:\\Users\\.....\\test.xlsx");
FileInputStream fileInputStream = new FileInputStream(file);
Workbook wb = new XSSFWorkbook(fileInputStream);
thanks
After spending days on this problem I found an answer in stackoverflow )). FileInputStream vs ClassPathResource vs getResourceAsStream and file integrity
the problem in maven-resources-plugin filtering, it corrupts excel file .
You should not filter binary files like excel and use two mutually exclusive resource sets as described at the bottom of this page
Adding more information to @user1321466 answer, to filter you can do as described in maven resources plugin site:
If you have both text files and binary files as resources it is recommended to have two separated folders. One folder src/main/resources (default) for the resources which are not filtered and another folder src/main/resources-filtered for the resources which are filtered.
or just exclude the files from filtering:
<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>
Is the file at the top of the classpath, i.e. in WEB-INF/classes?
The API doc for Classloader.getResource() says the resource name is:
"The name of a resource is a '/'-separated path name that identifies the resource."
So if your file is in some subdirectory, that path should be part of the resource name.
来源:https://stackoverflow.com/questions/27387365/read-excel-filewhich-is-in-classpath-via-apache-poi