Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Como usar o p:fileDownload para baixar um arquivo específico

Tenho um datatable e quero implementar um botão de download para baixar o arquivo pdf daquela linha específica. Já consegui implementar o p:fileUpload e agora quero baixar esse arquivo que foi feito o upload.

Meu método upload

public void upload(FileUploadEvent evento) {
        try {
            UploadedFile arquivoUpload = evento.getFile();
            Path arquivoTemp = Files.createTempFile(null, null);
            Files.copy(arquivoUpload.getInputstream(), arquivoTemp, StandardCopyOption.REPLACE_EXISTING);
            monografia.setCaminho(arquivoTemp.toString());

            Messages.addGlobalInfo("Upload realizado com sucesso");
        } catch (IOException erro) {
            Messages.addGlobalInfo("Ocorreu um erro ao tentar realizar o upload de arquivo");
            erro.printStackTrace();
        }
    }
4 respostas

Oi Daniel,

Pode ser feito utilizando o componente p:fileDownload:

<p:column headerText="Download">
    <p:commandButton ajax="false" actionListener="#{bean.download(monografia)}">
        <p:fileDownload value="#{ben.file}" />
    </p:commandButton>
</p:column>
public class Bean {

    private Monografia selecionada;
    private StreamedContent file;

    public StreamedContent getFile() throws FileNotFoundException {
        InputStream stream = new FileInputStream("caminho do arquivo");
        file = new DefaultStreamedContent(stream, "application/pdf", "download.pdf");
        return file;
    }

    public void download(Monografia selecionada) {
        this.selecionada = selecionada;
    }
}

Desse jeito, quando você clicar no botão de download, o primefaces vai chamar o método download para setar o registro que foi clicado, e o componente p:fileDownload vai chamar o método getFile para realizar o download do arquivo.

Veja se funciona.

Bons estudos!

Olá Rodrigo, não consegui fazer, você poderia explicar melhor, porque pelo showcase do Primefaces também não consegui.

Aqui está meu método salvar, que eu eu uso para que ele pegue o arquivo da pasta temporária e jogue para outra pasta. Então quando eu selecionar ou clicar em download ele baixe o arquivo daquela Monografia específica

public void salvar(){
        try {

            Path origem = Paths.get(monografia.getCaminho());
            Path destino = Paths.get("C:/Uploads/Monografia/" + monografia.getTitulo() + ".pdf");

            Files.copy(origem, destino, StandardCopyOption.REPLACE_EXISTING);

            cadastroMonografiaService.salvar(monografia);

            atualizarRegistros();

            messages.info("Monografia salva com sucesso!");

            RequestContext.getCurrentInstance().update(Arrays.asList("frm:monografiasDataTable", "frm:messages"));

        } catch (Exception erro) {
            messages.alerta("Erro ao salvar a Monografia!");
            erro.printStackTrace();
        }
    }

Oi Daniel,

Não vi provlemas no seu código de salvar. Você conferiu se ele está realmente copiando o arquivo pdf para a pasta após salvar?

E qual foi o erro que aconteceu quando você clicou para fazer o download?

solução!

Oi Rodrigo,

Consegui resolver o modificando o componente p:fileDownload. Adicionei o "immediate" e tirei o actionListener. O problema que ocorria era de mostrar validações de diversos campos na tela quando clicava em download.

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