Java 下载excel模板下载之后无法正常打开,提示损坏

简单版:resources 目录下放模板 excel 文件,通过接口下载后,有文件,但打不开。

解决:maven 构建时对该 excel 模板进行了过滤,导致文件损坏,解决办法,在过滤的时候把 xlsx 排除掉(<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>)。

<build>
	<plugins>
    	<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <nonFilteredFileExtensions>
						<!--不加这一行,xlsx文件会被过滤,然后在maven build的时候,去target下看对应的xlsx就是损坏的-->
                        <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
        </plugin>
    </plugins>
</build>

具体过程

问题: springboot 项目简单的下载excel 模板功能,模板放在resources/template/目录中,

public static void downloadTemplate(String downloadName, String classPath) {
    // 处理下中文乱码问题获取response
    HttpServletResponse response = ResponseUtils.getHttpResponse(downloadName + XLSX);
    try (InputStream inputStream = new ClassPathResource(classPath).getStream();
         OutputStream outputStream = response.getOutputStream()) {
        IOUtils.copy(inputStream, outputStream);
    } catch (IOException e) {
        log.error(String.format("下载%s失败", downloadName), e);
    }
}

代码挺简单,一运行,也挺顺利,很快就把文件下好了。点开看看,咦,怎么回事,怎么提示我可能是内存不足,不足以打开这个文件呢?

尝试一

当时电脑也有点卡,心想可能是内存不够了,关了一些文件,还是无法正常打开;而打开那个模板文件就是正常的。排除提示的情况, 确定是文件出错了。

尝试二

代码是直接从之前做的项目直接拷贝的,之前运行的都没问题,按理来说,也应该没问题啊。直接去搜 java excel下载无法打开, 有说什么 Response 要设置 Content-Length 才行。试了一下还是不行。

尝试三

直接尝试从本地文件的 excel 文件,写到另一个文件,发现可以正常写入;从 classpath读取,写入失败。也就是,从 classpath 读取的时候,就是一个有问题的 excel 文件。

尝试四

之前一直着眼于代码结构中的模板文件了,后来想到, 太傻了, 要去 target 目录下去看看才是。打开一看,好家伙,编译过后的 excel 文件就是损坏的。

尝试五

这个时候才想到搜索时有文章提到 maven 的 filtering,发现是 <filtering>true</filtering>

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
            <include>**/*.json</include>
            <include>**/*.ftl</include>
        </includes>
    </resource>
</resources>

当然,粗暴一点解决就是改为 false, 以前的项目也一直是 false;当中也试了很多 <excludes>,现在看起来是白费力气, 它喵的, <excludes> 就直接排除了,你重新 mvn clean compile 的时候,直接看不到 excel 模板了。最后还是采用了开头描述的方案。
至于为什么会损坏,只在官网文档(https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html)找到这样一句话:Warning: Do not filter files with binary content like images! This will most likely result in corrupt output.

总结

有的时候,程序报的错误会误导我们,尽管它告诉我们错误是由于“原因a”引起的,但排查到最后,可能是“原因z”引起的。在遇到问题的时候,我们就应该仔细思考一下,哪些是没问题的,有哪些可能导致了问题的发生。而不是被某个错误原因所误导。

虽然问题还是比较简单,但还是耗费了不少时间趟这条弯路。因此记录一下,作为警示。

posted @ 2022-10-13 22:33  Code&Fight  阅读(3670)  评论(0编辑  收藏  举报