我把Excel文件放在resources/template/a.xlsx
中,我把它和mvn package
打包,我想和一个API从这个jar下载.xlsx。
我的API:
public void downloadExcelTemplate(RoutingContext routingContext) {
String fileName = "a.xlsx";
String path = "template" + File.separator+fileName;
HttpServerResponse response = routingContext.response();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(path)));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = in.readLine()) != null){
buffer.append(line);
}
response.putHeader("content-type", "application/octet-stream;charset=UTF-8");
response.putHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
response.putHeader("Pragma", "no-cache");
response.putHeader("Cache-Control", "no-cache");
response.setChunked(true);
response.write(buffer.toString());
} catch (IOException e) {
logger.error("error: ", e);
}
response.end();
}
我使用vertx.web和Spring,poi依赖项是:
<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-beta1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17-beta1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-excelant</artifactId>
<version>3.17-beta1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.17-beta1</version>
</dependency>
我认为SpringMVC和vertx.web在下载时是一样的,但当我尝试下载时,下载的xlsx文件无法打开。
在这种情况下,不要使用java.io.Reader!
xlsx文件是二进制的(从技术上讲,它们是zip文件(。
使用读卡器会损坏数据
public void downloadExcelTemplate(RoutingContext routingContext) {
String fileName = "a.xlsx";
String path = "template" + File.separator+fileName;
HttpServerResponse response = routingContext.response();
try(final InputStream inputStream =
this.getClass().getClassLoader().getResourceAsStream(path);
final BufferedInputStream in =
new BufferedInputStream(inputStream); ) {
// Use the actual content type for the file
response.putHeader("content-type",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.putHeader("Content-Disposition",
"attachment;filename=" +
new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
response.putHeader("Pragma", "no-cache");
response.putHeader("Cache-Control", "no-cache");
response.setChunked(true);
// Vert.x Buffer Object
Buffer buffer = Buffer.buffer()
byte[] rawBuffer = new byte[1024];
int numRead;
while((numRead = is.read(rawBuffer, 0, rawBuffer.length)) != -1) {
response.appendBytes(rawBuffer, 0, numRead);
}
response.write(buffer);
} catch (IOException e) {
logger.error("error: ", e);
}
response.end();
}
}
资源路径区分大小写,并使用斜线(/
(作为路径分隔符。
响应是一个二进制文件,而不是文本。因此,它必须由InputStream加载,并由OutputStream编写。读写器支持Unicode文本,并且总是暗示二进制字节的字符集转换。这会破坏事物,或者至少会使它们变慢。
public void downloadExcelTemplate(RoutingContext routingContext) {
String fileName = "a.xlsx";
String path = "template/" + fileName;
HttpServerResponse response = routingContext.response();
try {
URL url = getClass().getClassLoader().getResource(path);
Path path = Paths.get(url.toURI());
response.putHeader("Content-Type", "application/octet-stream;charset=UTF-8");
response.putHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName,"ISO-8859-1"));
response.putHeader("Pragma", "no-cache");
response.putHeader("Cache-Control", "no-cache");
response.setChunked(true);
// It would have been nice to do just: Files.copy(path, response.getOutputStream());
byte[] content = Files.readAllBytes(path);
Buffer buffer = Buffer.buffer(content);
response.write(buffer);
} catch (IOException e) {
logger.error("error: ", e);
}
response.end();
}
不确定";;charset=UTF-8";用于内容类型。Excel内部使用UTF-8?不应该被需要。
很高兴回复您。首先,您应该将MVN包视为导致excel无法打开的罐子。
然后,您可以尝试其他源路径进行访问。
最后,您可以尝试在jar的同一文件目录中拍摄excel以进行访问。我认为这没关系。我向你问好。Allen