Java从Jar包下载xlsx文件问题:下载后文件无法正常打开
解决Vert.x Web下载XLSX文件损坏的问题
你遇到的核心问题是用文本流方式读取二进制的XLSX文件,导致文件结构被破坏,所以下载后无法打开。XLSX本质是ZIP压缩包,必须用二进制流处理,不能用BufferedReader这类文本处理工具。下面是具体的修复方案:
关键问题分析
你的代码中使用InputStreamReader和BufferedReader读取文件,这两个类是专门处理文本文件的,会把二进制字节转换成字符编码,过程中会丢失或篡改XLSX的二进制信息,最终导致文件损坏。
修正后的下载代码
结合Vert.x Web的异步特性,直接操作二进制输入流来实现下载:
import io.vertx.core.http.HttpServerResponse; import io.vertx.ext.web.RoutingContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; public class YourController { private static final Logger logger = LoggerFactory.getLogger(YourController.class); public void downloadExcelTemplate(RoutingContext routingContext) { String fileName = "a.xlsx"; // Classpath路径用斜杠,跨平台更可靠,避免File.separator的平台差异 String resourcePath = "template/" + fileName; HttpServerResponse response = routingContext.response(); // 用try-with-resources自动关闭输入流,防止资源泄漏 try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(resourcePath)) { if (inputStream == null) { // 处理文件不存在的情况 response.setStatusCode(404).end("Excel template not found"); return; } // 设置标准的XLSX MIME类型,比application/octet-stream更准确 response.putHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 处理文件名中文乱码问题 String encodedFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); response.putHeader("Content-Disposition", "attachment;filename=" + encodedFileName); response.putHeader("Pragma", "no-cache"); response.putHeader("Cache-Control", "no-cache"); // 用Vert.x的sendStream直接发送二进制流,符合异步IO模型 response.sendStream(inputStream); } catch (IOException e) { logger.error("Failed to download Excel template", e); response.setStatusCode(500).end("Download failed due to server error"); } } }
额外优化建议
1. 统一POI依赖版本
你当前的POI依赖混合了正式版和beta版,beta版本可能存在稳定性问题,建议全部换成正式版3.17:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <!-- 如果不需要Excel自动化测试和旧版Office格式支持,可以移除以下两个依赖 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.17</version> </dependency>
2. 确认文件打包情况
执行mvn package后,检查生成的JAR包内是否包含template/a.xlsx文件(可以用解压工具打开JAR查看),确保resources/template/a.xlsx被正确打包到classpath根目录下的template文件夹中。
内容的提问来源于stack exchange,提问作者Rollsbean
相关产品推荐
相关产品推荐

