如何从 java 中的 jar 下载现有的 xlsx 文件

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文件打不开。

在这种情况下不要为此使用 java.io.Reader!

xlsx 文件是二进制文件(从技术上讲它们是 zip 文件)。

使用Reader会破坏数据

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();
    }
}

很高兴回复你。 首先,你应该考虑MVN打包成jar导致你的excel打不开

那么,您可以尝试其他源路径访问。

最后可以尝试将excel电影放在jar的同一个文件目录下访问。我觉得没问题。 我对你最好。艾伦

资源路径是 case-sensitive 并使用斜杠 (/) 作为路径分隔符。

响应是二进制文件,不是文本。因此它必须由 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 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?应该不需要。