Generate PDF with Jasper and download without storing it

Asked

Viewed 2,674 times

5

I’m generating a PDF with Jasper, I’ll show you how it’s being done.

I’m saving it on disk, storing the path in the bank and then downloading it. I would like to know how to make so that the moment I click to generate, it generate and already download. I am using the file Download primefaces.

How To Make It Before Not Save, Just Download?

public void imprimirRelatorio(GeradorEdital[] g) throws IOException, ParseException {

// O g é o meu dataSource. 

private StreamedContent file;
HashMap parametros = new HashMap();
parametros.put("ID_EDITAL", edital.getIdEdital());
FacesContext facesContext = FacesContext.getCurrentInstance();

try {

    JRBeanArrayDataSource arrayDs = new JRBeanArrayDataSource(g, false);
    String caminhoWebInf = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/WEB-INF/");
    String caminhoReports = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/WEB-INF/reports");

    JasperPrint impressoraJasper = JasperFillManager.fillReport(caminhoWebInf+"\\reports\\Edital.jasper", parametros, arrayDs);

    String caminhoFinal = "\\edital"+""+edital.getTitulo()+""+edital.getDataCriacao().getTime();

    File pdf = new File(caminhoReports+caminhoFinal);
    pdf.createNewFile();
    FileOutputStream arquivo = new FileOutputStream(pdf);

    JasperExportManager.exportReportToPdfStream(impressoraJasper, arquivo);

    edital.setSrcPDF("//reports/"+caminhoFinal);
    editalDAO.atualizarEdital(edital);

    edital = null;
    disciplinaBean.setDroppedDisciplinas(null);

    arquivo.flush();
    arquivo.close();


    } catch (JRException e) {
        e.printStackTrace();
    }
}


    public void setFile(StreamedContent file) {
         this.file = file;
    }

public StreamedContent getFile() throws FileNotFoundException {

    String caminhoWebInf = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/WEB-INF/");
    InputStream stream = new FileInputStream(caminhoWebInf+editalSelecionado.getSrcPDF());  
    file = new DefaultStreamedContent(stream, "application/pdf", editalSelecionado.getTitulo()+".pdf");  

    return file;  
}

The button in . xhtml:

<p:commandButton ajax="false" onclick="PrimeFaces.monitorDownload(start, stop);" 
                icon="ui-icon-arrowthick-1-s">  
                             <p:fileDownload value="#{editalBean.file}" /> 
</p:commandButton>

2 answers

1

Change your FileInputStream by a ByteArrayOutputStream; save the byte array generated by it, and then use a ByteArrayInputStream in place of FileInputStream; in this way, the whole process will be carried out in RAM.

Keep in mind, however, that for large reports this will "devour" the server memory; it may be more appropriate to use File.createTempFile().

0

You can change the header by placing:

            HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
            response.reset();
            response.setContentType("application/pdf");//inline;attachment;
            response.setHeader("Content-disposition", "inline; filename=" + nomedegravacaodorelatorio + ".pdf");
            response.setContentLength(bytes.length);
            servletOutputStream = response.getOutputStream();
            JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
            servletOutputStream.write(bytes, 0, bytes.length);
            servletOutputStream.flush();
            servletOutputStream.close();
            facesContext.renderResponse();
            facesContext.responseComplete();

The "Content-disposition", "inline; filename=" command in the header warns the browser that it is not for saving, unlike the "Content-Disposition", "Attachment; filename= "report.pdf ""); command that in this case the code asks to save the pdf. I hope I’ve helped.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.