Search code examples
javaspring-mvcvert.xcontent-disposition

How to download existed xlsx file from jar in java


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.


Solution

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