[RESOLVIDO] Exibir pdf na pagina ou imprimir diretamente JSF 2.0 + primefaces

16 respostas
C
Olá a todos, bom estou tentando sem sucesso exibir um relatório em pdf diretamente na pagina, sei que existem milhoes de exemplos de códigos por ai, mas o fato é q eu já tentei vários, e simplesmente não acontece nd ao clicar no meu commandbutton. é assim, em determinada parte do site, o usuario faz um pedido de orçamento, e ao salvar, eu usei o compomente p:filedownload do prime, para dar opção do usuario baixar o pdf do relatorio, mas em outra parte do site, os funcionarios da empresa devem ter uma opção de visualizar esse relatório diretamente na pagina, sem precisar fazer (download, salvar e dai abrir), ou então imprimir ele também diretamente sem vizualizar, e isso eu nao estou conseguindo fazer, já tentei usar vários codigos como o abaixo, com pequenas diferenças, mas quando executa, nada acontece no browser... Lembrando q estou usando jsf 2.0 e primefaces, será q tem algo a ver com a forma q o navegador do jsf trata as requisições, atraves de forward ? se sim, alguem tem idéia de como resolver?
public void visualizarRelatorio() {
        try {
            System.out.println("entrou no visualizar relatorio");
            if (orcamentoSelecionado == null) {
                return;
            }
            //---------- gera o relatorio ----------
            HashMap parametros = new HashMap();
            parametros.put("orcamento", orcamentoSelecionado);

            JasperReport jasperReport = JasperCompileManager.compileReport(getClass().getResourceAsStream("/relatorios/PedidoDeOrcamento.jrxml"));
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parametros, new JRBeanCollectionDataSource(itens));
            byte[] b = JasperExportManager.exportReportToPdf(jasperPrint); 

            HttpServletResponse res = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
            res.setContentType("application/pdf");
            //Código abaixo gerar o relatório e disponibiliza diretamente na página 
            res.setHeader("Content-disposition", "inline;filename=arquivo.pdf");
            //Código abaixo gerar o relatório e disponibiliza para o cliente baixar ou salvar 
            //res.setHeader("Content-disposition", "attachment;filename=arquivo.pdf");
            res.getOutputStream().write(b);
            res.getCharacterEncoding();
            FacesContext.getCurrentInstance().responseComplete();
            System.out.println("saiu do visualizar relatorio");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
***EDIT *** faltou o código do commandbutton
<p:commandButton value="Visualizar relatório"
                             action="#{mBConsultarOrcamentos.visualizarRelatorio()}" 
                             style="width: 50px;font-family: Tahoma;font-size: 12px"/>
Desde já grato ! t+

16 Respostas

D

mude o comandButton de p para h!

<h:commandButton value="Visualizar relatório" action="#{mBConsultarOrcamentos.visualizarRelatorio()}" style="width: 50px;font-family: Tahoma;font-size: 12px"/>
Quanto a ver o PDF direto no browser tem mais haver com o pdf reader que voce instalaou por exemplo o foxit te da opcao de visualizar o pdf no browser. Acho que a resposta chega ao browser (com o tipo) a decisao de abrir direto no browser ou nao e dependente do browser e dos aplicativos instalados na maquina do usuario.

C

hahaha valeu dreampeppers99, mudar do commandbutton do prime para o do jsf resolveu, eu uso o acrobat reader aqui, ele abriu certinho no browser, só q o command button perdeu a formatação do theme do primefaces, ficou cinza normal…

e para imprimir diretamente, vc tem idéia de como se faz?

D

Nao :frowning:

A

para vc executar o metodo do relatorio com p:commandButton, vc tem q setar a opção ajax para false.

flw

L

Pra exibir diretamente, podes usar o JasperViewer, mas vai abrir janela.
Pra exibir o pdf diretamente na página, inclusive com controle, eu indico sempre o icePDF.
Abraço!

C

valeu alissonvla, funcionou, e quanto a imprimir direto, vou deixar quieto, vou disponibilizar somente um botão “vizualizar” e dai se quizer imprimir, o cara imprime pelo plugin pdf instalado no browser, no meu caso o adobe…

desculpe as nubice ai pessoal, sei que esses detalhes sao coisas simples, mas o fato é q eles acabam atrapalhando e muito a vida de quem tah começando a programar pra web como eu

vlw a ajuda ai t+

C

leoramos, mas se usar o jasperviewer, nao vai exibir no lado servidor?

P

Resolvi o meu problema utilizando Servlet.

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

/**
 *
 * @author Paulo Vinícius Moreira Dutra
 * @version 1.0
 * 
 */
@WebServlet(name = "RelatorioServlet", urlPatterns = {"/RelatorioServlet"})
public class RelatorioServlet extends HttpServlet {                 
    
    public static final String IMAGES_DIR = "/br/requisitebuilder/relatorios/";  
    
    public static final String IMAGE_LOGO = "logo.png";         
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setHeader("application/pdf", "Content-Type");  
        response.setContentType("application/pdf");
        
        //Para download
        //   response.setContentType("application/vnd.ms-excel");  
        //response.setHeader("Content-Disposition","attachment;filename=relatorioExcel.xls"); 
        InputStream caminho = null;
        
        ServletOutputStream ouputStream = null;               
        
        try{                         
             
             List listagem = new ArrayList();
    
             HttpSession session = request.getSession(true);                          
             
             Object attribute = session.getAttribute("listagem");
             String relatorio = session.getAttribute("relatorio").toString();           
             
             System.out.println(attribute);
             System.out.println(relatorio);
             
             if (attribute instanceof List);             
                listagem = (List)attribute;
             
             if (listagem == null)
                 listagem = new ArrayList();
             
             String logoPath = IMAGES_DIR + IMAGE_LOGO;
             
             caminho = Report.class.getResourceAsStream(relatorio);
             
             System.out.println(caminho);
             
             HashMap parametros = new HashMap();
             parametros.put("IMAGE_TOPO", logoPath );
                 
             JRDataSource jrds = new JRBeanCollectionDataSource(listagem);  
             JasperPrint preencher = JasperFillManager.fillReport(caminho, parametros, jrds);
                        
             byte[] bytes = JasperExportManager.exportReportToPdf(preencher);
           
             response.setContentLength(bytes.length);                   
             
             ouputStream = response.getOutputStream();  
             ouputStream.write(bytes, 0, bytes.length);               
             
             ouputStream.flush();
             
         }catch(Exception e){
             e.printStackTrace();         
         }finally {
            
            if (caminho != null)
                caminho.close();
            
            if (ouputStream != null)
                ouputStream.close();
            
         }
        
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
    
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
Na minha classe ManagedBean adicionei um método para redirecionar o o servelt
protected void redirect(String page){

        FacesContext ctx = FacesContext.getCurrentInstance();
        ExternalContext ec = ctx.getExternalContext();                
                
        try {
            ec.redirect(ec.getRequestContextPath() + page);
        } catch (IOException ex) {
            addMessageErro(ex.getMessage());
        }

    }   
    
    public void imprimirRelatorio() throws Exception{  

         try
         {
             
            FacesContext ctx = FacesContext.getCurrentInstance();
            HttpSession session = (HttpSession) ctx.getExternalContext().getSession(false);                         
            session.setAttribute("listagem", listagem);
            session.setAttribute("relatorio", "Requisitos.jasper");
            
            redirect("/RelatorioServlet");
   
         }catch(Exception ex){
             addMessageErro(ex.getMessage());             
         }
         
    }
Na minha página JSF o comandButton do primefaces
<p:commandButton id="btnRelatorio"
                                   value="Relatório"
                                   immediate="false"
                                    action="#{requisitoMB.imprimirRelatorio}"
                                    styleClass="btnNovo"
                                    style="text-align: center; width: 100px; 
                                     margin: 0 auto; border-style: solid; ">
     </p:commandButton>
G

show de bola, paulo!
Mas me diga uma coisa pq n colocou ajax=“false” no componente do prime? vc colocou immediat=“false” são a mesma coisa?

P

gambazinho:
show de bola, paulo!
Mas me diga uma coisa pq n colocou ajax=“false” no componente do prime? vc colocou immediat=“false” são a mesma coisa?

Na verdade você pode omitir o parâmetro immediate=false, pois eu estava realizando alguns teste.

Abraços

G
cleiton herrmann:
public void visualizarRelatorio() {
        try {
            System.out.println("entrou no visualizar relatorio");
            if (orcamentoSelecionado == null) {
                return;
            }
            //---------- gera o relatorio ----------
            HashMap parametros = new HashMap();
            parametros.put("orcamento", orcamentoSelecionado);

            JasperReport jasperReport = JasperCompileManager.compileReport(getClass().getResourceAsStream("/relatorios/PedidoDeOrcamento.jrxml"));
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parametros, new JRBeanCollectionDataSource(itens));
            byte[] b = JasperExportManager.exportReportToPdf(jasperPrint); 

            HttpServletResponse res = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
            res.setContentType("application/pdf");
            //Código abaixo gerar o relatório e disponibiliza diretamente na página 
            res.setHeader("Content-disposition", "inline;filename=arquivo.pdf");
            //Código abaixo gerar o relatório e disponibiliza para o cliente baixar ou salvar 
            //res.setHeader("Content-disposition", "attachment;filename=arquivo.pdf");
            res.getOutputStream().write(b);
            res.getCharacterEncoding();
            FacesContext.getCurrentInstance().responseComplete();
            System.out.println("saiu do visualizar relatorio");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
Eu preciso fazer a mesma coisa contudo quero dar a opção pro usuário abrir/baixar o arquivo .pdf em vez de exibir em tela. Se eu alterar a linha:
//Código abaixo gerar o relatório e disponibiliza diretamente na página 
            res.setHeader("Content-disposition", "inline;filename=arquivo.pdf");
para:
//Código abaixo gerar o relatório e disponibiliza para o cliente baixar ou salvar 
            //res.setHeader("Content-disposition", "attachment;filename=arquivo.pdf");
Vai resolver ou preciso alterar mais alguma coisa?

Outra dúvida, o teu diretório: "/relatorios/PedidoDeOrcamento.jrxml" está abaixo diretamente da raíz da aplicação?

C

gRoOve, salvo engano, nao precisa alterar mais nada não…

quanto ao diretório, ele esta na raiz do projeto, junto com outros diretorios como util, cfg, beans, dao, enfim…

vlw t+

G

Por favor, alguém consegue me ajudar, já estou 2 semanas tentando fazer esse relatório e não consigo =((
Meu código executa sem erro mas não acontece NADAA.

public void gerarRelatorio() throws IOException {
		try {
			System.out.println("entrou no visualizar relatorio");

			InputStream is = getClass().getResourceAsStream("RelatorioCategoriaPorNome.jasper");

			Map<String, Object> parametro = new HashMap<String, Object>();
			parametro.put("nomeCategoria", "bar");

			JasperPrint jasperPrint = JasperFillManager.fillReport(is, parametro, ConnectionFactory.getTurismoGuiadoConnection());
			byte[] b = JasperExportManager.exportReportToPdf(jasperPrint);

			HttpServletResponse res = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
			res.setContentType("application/pdf");
			//Código abaixo gerar o relatório e disponibiliza diretamente na página   
			res.setHeader("Content-disposition", "attachment;filename=arquivo.pdf");
			res.getOutputStream().write(b);
			res.getCharacterEncoding();
			FacesContext.getCurrentInstance().responseComplete();
			System.out.println("saiu do visualizar relatorio");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
P

Com relação ao botão do primefaces sem o css do componente, na verdade você não precisa usar o <h:commandButton> pode utilizar o <p:commandButton ajax="false" /> vai funcionar.

R

Boa tarde,
estou tentando usar essa forma que vc colocou acima, poderia me falar certinho qual as bibliotecas tem que importar.

B

Bom dia

Desculpe reabrir a discussão ai. Sua solução esta funcionando perfeitamente aqui para mim paulofafism.

<p:column style="width:30px;" headerText="Texto">
						<p:commandButton action="#{proposicaoBean.imprimirDocumento}" icon="ui-icon-circle-zoomin" title="Texto" 
							ajax="false" onclick="this.form.target='_blank'" 
							style="width:20px;height:20px;">							
							<f:setPropertyActionListener value="#{obj}"	target="#{proposicaoBean.legRotinaWrapperSelecionada}"/>							
						</p:commandButton>
					</p:column>

Tenho isso dentro de um grid paginado ( paginação padrão do prime ). Listo 20 registros por página, se clicar em um por um visualiza tudo beleza.

Ao mudar de página (vou para a página 5 da listagem por exemplo), ao clicar no botão visualizar ele abre uma página nova no primefaces, ou seja ignorando minhas funções. A página aberta é a mesma daonde eu cliquei só que volta para a pagina 1.

Alguma dica do que poderia ser?

Criado 26 de julho de 2011
Ultima resposta 15 de mai. de 2014
Respostas 16
Participantes 10