How to download a . pdf file with JSF?

Asked

Viewed 6,933 times

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, this way:

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

He’s safe in that directory:

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

How do I put a button that downloads this report? I tried to use the download component of primefaces but did not, when I step this way it says that Resource is not valid.

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 that this method is not called by an Ajax request. If you are using the library Omnifaces, one of the methods may be used Faces#sendfile to download a file.

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

References Font¹, Source²

  • It may look stupid. But as I write the Inputstream for Outputstream?

  • @Joãoneto I edited the answer, see if it works for you.

  • Yes, it worked! But after this way I managed to do it also using the component of the primefaces. I will post my solution as well.

  • @Joãoneto I’m glad it worked out. If you can mark the answer as accepted. =)

  • I’d forgotten that kkk detail. =)

2

I got the solution with the first solution of the answer of Qmechanic73, but soon after also I was able to do 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;  
    } 

Browser other questions tagged

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