英文:
How to download existed xlsx file from jar in java
问题
我将Excel文件放在resources/template/a.xlsx
中,然后使用mvn package
进行打包,我想要添加一个API来从这个jar包中下载a.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文件无法打开。
英文:
I put Excel file in resources/template/a.xlsx
, i package it with mvn package
, i want to and a API to download a.xlsx from this jar.
My 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();
}
I use vertx.web and Spring, poi dependency is:
<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>
I think SpringMVC and vertx.web is same in download, but when i try to download, the download xlsx file couldn't be open.
答案1
得分: 2
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); ) {
// 使用文件的实际内容类型
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 buffer = Buffer.buffer();
byte[] rawBuffer = new byte[1024];
int numRead;
while((numRead = in.read(rawBuffer, 0, rawBuffer.length)) != -1) {
buffer.appendBytes(rawBuffer, 0, numRead);
}
response.write(buffer);
} catch (IOException e) {
logger.error("error: ", e);
}
response.end();
}
}
英文:
DO NOT in this case USE java.io.Reader for this!
xlsx files are binary (technically they're zip files).
Using Reader will corrupt the data
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();
}
}
答案2
得分: 1
资源路径区分大小写,并使用斜杠(/
)作为路径分隔符。
响应是一个二进制文件,而不是文本。因此必须使用InputStream加载它,并使用OutputStream写入它。读取器(Readers)和写入器(Writers)用于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 filePath = 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);
// 希望能够只写:Files.copy(filePath, response.getOutputStream());
byte[] content = Files.readAllBytes(filePath);
Buffer buffer = Buffer.buffer(content);
response.write(buffer);
} catch (IOException | URISyntaxException e) {
logger.error("error: ", e);
}
response.end();
}
不确定在内容类型中使用";charset=UTF-8"的影响是什么。Excel内部使用UTF-8吗?应该不是必需的。
英文:
Resource paths are case-sensitive and use a slash (/
) as path separator.
The response is a binary file, not a text. Hence it must loaded by an InputStream, and written by an OutputStream. Readers and Writers are for Unicode text and always imply a charset conversion for the binary bytes. Which would corrupt things or at least make them slow.
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();
}
Not sure what the effect is of ";charset=UTF-8" for the content type. That Excel internally uses UTF-8? Should not be needed.
答案3
得分: -1
很高兴回复你。
首先,你应该考虑将MVN包转换为一个jar文件,导致你的Excel无法打开。
然后,你可以尝试另一个源路径来访问。
最后,你可以尝试将Excel文件移动到jar文件相同的目录中进行访问。我认为那样应该可以。
祝你一切顺利。艾伦
英文:
Nice to reply to you.
First, you ought to consider the MVN package to a jar lead to your excel that can not open.
Then, you can try another source path to access.
Finally, you can try to movie the excel at the jar's same file directory to access. I think that is OK.
My best to you. Allen
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论