How to download a .pdf file with JSF?

3

I'm using JSF and Primefaces, and I need to download a PDF that I generated with iReports and Jasper.

I save the PDF this way, in this path:

String caminhoReports = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/WEB-INF/reports");

File pdf = new File(caminhoReports+"/relatorio2.pdf");
            pdf.createNewFile();
            FileOutputStream arquivo = new FileOutputStream(pdf);
            JasperExportManager.exportReportToPdfStream(impressoraJasper, arquivo);

It is saved in this directory:

D:\Workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp4\wtpwebapps\monitorias\WEB-INF\reports\relatorio2.pdf

How do I put a button to download this report? I tried to use the download component of primefaces but it did not give, when I pass this path it says that the resource is not valid.

    
asked by anonymous 02.02.2015 / 00:04

2 answers

5

On a button call the method below.

// Aplicável ao JSF 2.x
private static final String PDF_URL = "http://.../file.pdf";

public void download() throws IOException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();

    response.reset();   // Algum filtro pode ter configurado alguns cabeçalhos no buffer de antemão. Queremos livrar-se deles, senão ele pode colidir.
    response.setHeader("Content-Type", "application/pdf");  // Define apenas o tipo de conteúdo, Utilize se necessário ServletContext#getMimeType() para detecção automática com base em nome de arquivo. 
    OutputStream responseOutputStream = response.getOutputStream();

    // Lê o conteúdo do PDF
    URL url = new URL(PDF_URL);
    InputStream pdfInputStream = url.openStream();

    // Lê o conteúdo do PDF e grava para saída
    byte[] bytesBuffer = new byte[2048];
    int bytesRead;
    while ((bytesRead = pdfInputStream.read(bytesBuffer)) > 0) {
        responseOutputStream.write(bytesBuffer, 0, bytesRead);
    }    
    responseOutputStream.flush();

    // Fecha os streams
    pdfInputStream.close();
    responseOutputStream.close();         
    facesContext.responseComplete();         
}

Make sure this method is not called by an Ajax request. If you are using the OmniFaces library, one of the methods Faces#sendfile to download a file.

public void download() throws IOException {
    Faces.sendFile(file, true);
}

References Font¹ , Font²

    
02.02.2015 / 00:37
2

I got the solution with the first QMechanic73 response solution, but soon after I was able to do it using the FileDownload component of PrimeFaces:

In my .xhtml

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

In my managedBean

private StreamedContent file;

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()); //Caminho onde está salvo o arquivo.
        file = new DefaultStreamedContent(stream, "application/pdf", "edital.pdf");  

        return file;  
    } 
    
03.02.2015 / 04:27