简体   繁体   中英

How to make a pdf appear as a download option rather than rendering on the browser?

I am using Jasper Reports in my project for producing the reports in multiple formats. Although all the code examples run fine, I have ran into a conceptual issue.

I wrote this trivial code which produces a PDF at the browser as a download option:

    @GET
    @Path("/basicdbreport")
    @Produces("application/pdf")
    public Response basicDbReport(@Context ServletContext context,
            @Context HttpServletResponse response) throws JRException,
            IOException {
        Connection connection = null;
        byte[] reportBytes = null;
        String reportName = "firstsqlexample";

        File file = new File(path + reportName + JASPER_EXTENSION);

        // check if compiled report exists
        if (!file.exists()) {
            compileReport(context.getRealPath(path + reportName + JRXML_EXTENSTION));
        }

        // input stream for filling the compiled report
        InputStream compiledReportStream = context.getResourceAsStream(path
                + reportName + JASPER_EXTENSION);

        try {
            connection = dataSource.getConnection();
            reportBytes = JasperRunManager.runReportToPdf(compiledReportStream,
                    new HashMap<String, Object>(), connection);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (reportBytes != null) {
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(reportBytes);
        }

        ResponseBuilder restResponse = Response.ok();
        restResponse.header("Content-Disposition",
                "attachment; filename=firstSQLReport.pdf");
        return restResponse.build();
    }

The code runs fine and I get a download prompt at the browser. However, when I dug deeper into the Jasper API I found a method runReportToPdfStream() method which would handle the output stream for me.

The new code looks something like this:

    @GET
    @Path("/basicdbreport")
    @Produces("application/pdf")
    public Response basicDbReport(@Context ServletContext context,
            @Context HttpServletResponse response) throws JRException,
            IOException {
        ServletOutputStream outputStream = response.getOutputStream();
        Connection connection = null;
        String reportName = "firstsqlexample";

        File file = new File(path + reportName + JASPER_EXTENSION);

        // check if compiled report exists
        if (!file.exists()) {
            compileReport(context.getRealPath(path + reportName + JRXML_EXTENSTION));
        }

        // input steam to fill complied report
        InputStream compiledReportStream = context.getResourceAsStream(path
                + reportName + JASPER_EXTENSION);

        try {
            connection = dataSource.getConnection();
            JasperRunManager.runReportToPdfStream(compiledReportStream, outputStream, new HashMap<String, Object>(), connection);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        ResponseBuilder restResponse = Response.ok();
        restResponse.header("Content-Disposition",
                "attachment; filename=firstSQLReport.pdf");
        return restResponse.build();
    }

The code runs fine but I do not get any download prompt , the pdf gets rendered on the browser instead. The response headers are as follows (on the browser):

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
Date: Wed, 21 Aug 2013 05:51:42 GMT

What's the reason that the code now fails to provide a download prompt? I am not an ace with HTTP but I guess this:

restResponse.header("Content-Disposition",
                    "attachment; filename=firstSQLReport.pdf");

is responsible for the download option. Its nowhere in the response although I did include it in the code. Please advice.

yes, you are right, Content-Disposition is the response header that you need to set to trigger the download action on the client browser.

i think you need to set the response headers first before writing to the response output stream.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM