背景
项目中遇到导出 excel 的需求,为求简便,直接在 excel 中创建了一张表作为模板,并放在 recourse/template中,后端从数据库读取数据后,利用模板创建一个 WorkBook,将数据填充后,导出即可。但是遇到了读取静态资源始终为 null 的问题,在此记录一下。
环境
springBoot、maven、vue、axios
目录结构
![](https://img.haomeiwen.com/i25166293/278922e9d9e7904d.png)
代码
InputStream excelInputStream = this.getClass().getResourceAsStream("/templates/项目投资费用明细.xls");
Workbook workbook = WorkbookFactory.create(excelInputStream);
通常这种情况都是路径错了,才会始终返回 null。但由上图可见,文件就在那,但是读不到,excelInputStream 始终为 null。
最后在一篇博客里面受到些启发: 彻底搞懂Class.getResource和ClassLoader.getResource的区别和底层原理。
看结果更直观一些,用 getResource() 方法辅助一下:
System.out.println(this.getClass().getResource("/"));
System.out.println(this.getClass().getClassLoader().getResource("/"));
System.out.println(this.getClass().getClassLoader().getResource(""));
输出结果为:
file:/F:/project/back-end/business/test-project/target/classes/
null
file:/F:/project/back-end/business/test-project/target/classes/
所以,根路径是 /target/classes,也就是打包后的路径,于是联想到是打包的问题,去这个路径下面找了一下,真的没有 /templates/项目投资费用明细.xls。手动拷贝一份到 /tartget/classes/resources/templates 中,再次运行问题就没了。于是乎检查了一下 pom,找到原因了:
![](https://img.haomeiwen.com/i25166293/dfe215f3b47fa5d9.png)
pom 中对打包做了规范,指定了打包的文件,增加 xls 的配置就行了。
<include>**/*.xls</include>
总结
两种可能:
- 有可能是路径错误;
- pom 对打包配置做了限制,检查一下 build → resources;
新的问题:
java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream
或
java.util.zip.ZipException: invalid block type
检查了一下 /tartget/classes/resources/templates 中的 excel, 要么是打不开,要么是打开了但是乱码。貌似 maven 在打包过程中,会对静态文件进行压缩,导致文件无法识别了。就是这个样子:
![](https://img.haomeiwen.com/i25166293/0182c4484d9057b7.png)
于是又在原来的基础上又增加了 filtering 为 false 的配置:
<includes>
<include>**/*.xls</include>
<include>**/*.xlsx</include>
</includes>
<filtering>false</filtering>
为了避免影响其他文件,我是创建了一个和resources并列的文件夹,专门用来存储excel模板,并按照上面配置了一下。
问题解决了。
另外,前端也需要对响应类型做出声明,否则也有可能出现乱码,responseType: "blob",
![](https://img.haomeiwen.com/i25166293/3dc5a5dd2caaf4f4.png)
网友评论