[RESOLVIDO ] Ireport gera relatorio, mas como faz para download?

24 respostas
EuclidesFilizola

Boa noite pessoal,

eu fiz um método para que fosse gerado meu relatorio através do click, e não ficasse salvo dentro do meu projeto.

public void gerarRelatorio(String caminhoRelatorio, JasperPrint print) throws IOException, JRException{
		
		
		FacesContext context = FacesContext.getCurrentInstance();

		HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

		ServletOutputStream responseStream = response.getOutputStream();

		InputStream caminho = getClass().getResourceAsStream(caminhoRelatorio);

		response.setContentType("application/pdf");
		
		response.setHeader("Content-Disposition","attachment; filename=\"relatorio.pdf\"");
	
		JasperExportManager.exportReportToPdfStream(print,responseStream);

		responseStream.flush();

		responseStream.close();

		context.renderResponse();

		context.responseComplete();

		JasperViewer.viewReport(print, false);

	
		
		
	}

Porém eu queria saber como eu faço para que o usuário ao clicar em “gerar relatorio” , pudesse fazer o download do arquivo.

E ainda tem outro problema, Não sei se é porque eu tenho o ireport instalado, mas com esse meu método, ao invés dele abrir o arquivo no Acrobat Reader , ele abre no jasper View,

isso está certo ?

24 Respostas

EuclidesFilizola

E ae moçada,

alguém para poder me ajudar ?

F

Isso ajuda?

byte[] lReportData = JasperRunManager.runReportToPdf(pathRelatorios
            + "report.jasper",vParametros,new JRBeanCollectionDataSource(list));
        
        if (lReportData != null && lReportData.length > 0){
            //response é um HttpServletResponse
            response.setContentType("application/pdf");
            response.setContentLength(lReportData.length);
            ServletOutputStream outputStream;
            try {
                outputStream = response.getOutputStream();
                outputStream.write(lReportData, 0, lReportData.length);
                outputStream.flush();
                outputStream.close();
            } catch (Exception e) {
                throw new JRException(e);
            } 
        }
EuclidesFilizola

Bom, testei da seguinte maneira:

String caminho = getDiretorioReal("/pages/relatorios/relatorios/RelatorioAbastecimento.jasper");
		
		JasperReport report = (JasperReport) JRLoader.loadObject(caminho);
		
		FacesContext context = FacesContext.getCurrentInstance();

		HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

		ServletOutputStream responseStream = response.getOutputStream();
		
		byte[] lReportData = JasperRunManager.runReportToPdf(report,map,ds);  
	          
	        if (lReportData != null && lReportData.length > 0){  
	            //response é um HttpServletResponse  
	            response.setContentType("application/pdf");  
	            response.setContentLength(lReportData.length);  
	              
	            try {  
	            	responseStream = response.getOutputStream();  
	            	responseStream.write(lReportData, 0, lReportData.length);  
	            	responseStream.flush();  
	            	responseStream.close();
	            	
	            	context.responseComplete();
	            	
	            } catch (Exception e) {  
	                throw new JRException(e);  
	            }   
	        }

e ele não me traz nenhum erro, mas também não me da nenhum sinal de vida,

não diz se o relatorio foi gerado, não avisa nada… coisa nenhuma… fica tudo parado…

o console do eclipse fica todo em branco.

e na view, nada acontece… !!!

alguem poderia me ajudar ???

EuclidesFilizola

Nada galera. ?

EuclidesFilizola

Bom dia,

ainda estou com esse problema.

Alguém pra me salvar ?

Polverini

cara eu estava com o mesmo problema seu ai achei esse tutorialzinho que me ajudou pra caramba

segue meus códigos:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum;
import net.sf.jasperreports.engine.util.JRLoader;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

/**
 *
 * @author mpolverini
 */
@ViewScoped
@ManagedBean
public class Rel implements Serializable {

    public StreamedContent getSampleReportPDF() {

        InputStream relatorio = null;

        try {

            String pdfFile = "C:\\sampleReport.pdf";

            ByteArrayOutputStream Teste = new ByteArrayOutputStream();

            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(getClass().getClassLoader().getResourceAsStream("Report/sampleReport.jasper"));
            jasperReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);

            List<Funcionario> list = new ArrayList<Funcionario>();

            Funcionario f = new Funcionario();

            Cargo c = new Cargo();

            c.setDescricao("CARGOOOOOO");
            c.setId(1);

            f.setId(1);
            f.setNome("NOME 01");
            f.setCargo(c);
            f.setEmail("EMAIL");

            list.add(f);

            f.setId(2);
            f.setNome("NOME 02");
            f.setCargo(c);
            f.setEmail("EMAIL");

            list.add(f);

            f.setId(3);
            f.setNome("NOME 03");
            f.setCargo(c);
            f.setEmail("EMAIL");

            list.add(f);

            f.setId(4);
            f.setNome("NOME 04");
            f.setCargo(c);
            f.setEmail("EMAIL");

            list.add(f);


            JRBeanCollectionDataSource datasource = new JRBeanCollectionDataSource(list);
            HashMap<String, Integer> params = new HashMap<String, Integer>();
            JasperPrint print = JasperFillManager.fillReport(jasperReport, params, datasource);

            JRExporter exporter = new net.sf.jasperreports.engine.export.JRPdfExporter();

            exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, Teste);
            exporter.exportReport();

            relatorio = new ByteArrayInputStream(Teste.toByteArray());

        } catch (JRException ex) {
            Logger.getLogger(Rel.class.getName()).log(Level.SEVERE, null, ex);
        }

        return new DefaultStreamedContent(relatorio);


    }
}
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <p:panel header="Teste Report">
                <p:commandButton rendered="true" id="exportar1" value="PDF" ajax="false">
                    <p:fileDownload value="#{rel.sampleReportPDF}" />
                </p:commandButton>
            </p:panel>
        </h:form>
    </h:body>
</html>

Espero ter ajudado =)

EuclidesFilizola

Beleza cara.

só está dando problema no seguinte

quando eu tento fazer essa linha

relatorio = new ByteArrayInputStream(Teste.toByteArray());

ele pede para que eu mude o objeto relatorio para 'ByteArrayInStream" .

e ae ?

EuclidesFilizola

Bem, ajeitei já essa parte.

agora me vem outro problema,

eu não tenho a classe “DefaultStreamContent” e nem a StreamedContent.

EuclidesFilizola

Ainda tem outro problema,

esse exemplo não servirá porque é para JSF 2.0,

e eu estou utilizando JSF 1.2 …

Polverini

Então as classes DefaultStreamContent e StreamedContent são do primeface (Uso a 2.2.1) e uso o jsf 2.0, de uma olhada em versões anteriores se o prime funciona no 1.2

EuclidesFilizola

Pode ser também a versão da biblioteca,

qual versão vc utiliza ?

Polverini

2.2.1 Primefaces e 2.04 Morraja JSF

EuclidesFilizola

Bom,

eu agora fiz o método da seguinte forma:

FacesContext context = FacesContext.getCurrentInstance();

HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

String diretorioReal = session.getServletContext().getRealPath("");

String caminhoRelatorio = diretorioReal+ "/pages/relatorios/RelatorioAbastecimento.jasper";

this.craConexao();
conexao = getConexao();

Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();

map.put("REPORT_CONNECTION",conexao);

ArrayList&lt;Abastecimento&gt; relatorio = new ArrayList&lt;Abastecimento&gt;();

relatorio = (ArrayList&lt;Abastecimento&gt;) abastecimentoService.retrieveAll();

JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(relatorio);

JasperReport reportx = (JasperReport) JRLoader.loadObject(caminhoRelatorio);

ServletOutputStream responseStream = response.getOutputStream();

byte[] ReportData = JasperRunManager.runReportToPdf(reportx,map,ds);

if (ReportData != null && ReportData.length&gt;0){

 response.setHeader("Content-Disposition","attachment; filename=\"relatorio.pdf\"");
 response.setContentType("application/pdf");
 response.setContentLength(ReportData.length);

  try{
    responseStream.write(ReportData,0,ReportData.length);
    responseStream.flush();
    responseStream.close();

    context.renderResponse();
    context.responseComplete();

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

     }

}

e me gerou o seguinte erro:

java.lang.NoSuchMethodError: com.lowagie.text.Image.plainWidth() F
EuclidesFilizola

Bom, já resolvi esse primeiro erro,

pois era uma imagem que eu estava tentando colcoar via MAP, mas eu retirei apenas para ver se o relatorio aparecia.

e INFELIZMENTE ,não apareceu.

ou seja,

eu clico em gerar,

e ele não faz nada, não mostra nenhum erro, não aparece o relatório, a interface grafica não mexe em nada…

e etc…

nada… me da sinal de vida… ¬¬

EuclidesFilizola

Agora deu o seguinte erro no firefox conforme imagem abaixo.


gilmatryx

Fala Euclides,

Essa imagem aí do firefox não é erro, na verdade é a representação binária do arquivo. Isso significa que o relatório foi enviado ao browser, mas o browser não chamou o aplicativo pdf.

Acho que deve ser problema no header da resposta. Seu código anterior tem aspas:

response.setHeader("Content-Disposition","attachment; filename=\"relatorio.pdf\"");  
response.setContentType("application/pdf");

Remova as aspas do filename e ver se funciona:

response.setHeader("Content-Disposition","attachment; filename=relatorio.pdf");  
response.setContentType("application/pdf");

Senão tente também mudar de attachment para inline.

EuclidesFilizola

Boa tarde gilmar,

continua do mesmo jeito.

Coloquei do jeito que vc falou e também tentei com o “inline”.

e nada…

gilmatryx

Por um a caso vc tem um leitor pdf instalado nesse computador em questão?
O firefox reconhece algum aplicativo associado ao tipo de arquivo pdf?
Quais são os headers enviados no retorno? (faça: na página com caracteres estranhos click como botão direito>propriedades da página)
Em salvar como, a página, vc consegue salvar um pdf?

EuclidesFilizola

tenho sim.

Gilmar,

se vc ler a primeira página desse post,

o método que eu utilizo funciona.

só que ele chama JasperViewer.show()

… e qual o problema nisso ???

ele ao invés de abrir o relatorio em um adobe acrobat, por exemplo,

ele já abre o jasper… do JasperReport,

vc está me entendendo ?

EuclidesFilizola

E ae galera…

ngm aqui pra me dar uma força hoje ??

EuclidesFilizola

Bom dia galera,

bem a forma que eu fiz agora está funcionando.

Eu tive que retirar o Ajax para funcionar, ou seja, eu troquei o a4j:commandButton, pelo h:commandButton,

e coloquei tudo dentro de um <h:form>.

e abaixo está o meu método que gera o relatório:

public void geraRelatorioPassandoListaDeObjetos() throws ClassNotFoundException, SQLException, JRException, IOException {
			
		// Conexão com o banco para o segundo relatório
		this.criaConexao();
		conexao = getConexao();
		
		// criação dos parametros
		Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();
		
		
		// conexão com o banco que será utilizada pelo subrelatório
		map.put("REPORT_CONNECTION", conexao);
		//map.put("IMAGE",diretorioReal+"/images/loma.jpg");
		
		// pego o caminho do diretório onde se encontra o subrelatório
		
		//map.put("SUBREPORT_DIR", getDiretorioReal("/pages/relatorios/relatorios/"));
		
		ArrayList&lt;Abastecimento&gt; relatorio =  new ArrayList&lt;Abastecimento&gt;(); 
			
		relatorio = (ArrayList&lt;Abastecimento&gt;) abastecimentoService.retrieveAll();
			
			//getListaAlunos(conexao);
		
		JRBeanCollectionDataSource ds = new
		JRBeanCollectionDataSource(relatorio);
		
		
		/*
		* Mando o jasper gerar o relatório. Nesse caso passo o map,
		* já que ele tem dois parâmetros que serão utilizados
		*/
		
		
		  
		FacesContext context = FacesContext.getCurrentInstance();  
		  
		HttpSession session = (HttpSession) context.getExternalContext().getSession(false);  
		HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();  
		  
		String diretorioReal = session.getServletContext().getRealPath("");  
		  
		String caminhoRelatorio = diretorioReal+ "/pages/relatorios/relatorios/RelatorioAbastecimento.jasper";  
	
		JasperPrint print = JasperFillManager.fillReport(caminhoRelatorio, map, ds);
		
		JasperExportManager.exportReportToPdfFile(print, diretorioReal+ "/pages/relatorios/relatorios/RelatorioAbastecimento.pdf");
		
		response.setContentType("application/octet-stream");
		
		response.setHeader("Content-Disposition", "attachment; filename=RelatorioAbastecimento.pdf");
		
		response.sendRedirect(context.getExternalContext().getRequestContextPath()
				 +
	                    "/pages/relatorios/relatorios/RelatorioAbastecimento.pdf");
		
		context.responseComplete();
		
		//	gerarRelatorio(caminhoRelatorio,print);
		
		//return "/RelatorioAbastecimento.pdf";
		}

Só tenho 2 observações a fazer ( para mim, ainda são 2 problemas)

Primeiro: ele só abre, depois que eu dou 2 cliques no botão. Ou seja,

se eu clicar a primeira vez, ele não faz nada. Mas na segunda, ele abre o relatório.

Segundo: O botão só funciona no FIREFOX, ou seja, eu testei no google Chrome, e ele não aparece … ele apenas da um refresh na página.

Vocês poderiam me ajudar ??

EuclidesFilizola

Bom galera,

agora funcionou.

Primeiramente eu tirei o a4j commandButton, e troquei pelo h:commandButton,

e é claro, para que isso funcionasse, eu tive que colocar tudo dentro de um h:form,

que antes não existia, pois era tudo facelets, sem o h:form.

Bom, enfim …

Só tem 2 observações a fazer:

a primeira é que, eu preciso dar 2 cliques para que “a ação” funcione, ou seja, se eu der apenas o primeiro clique, nada acontece …

tenho que dar um segundo clique…

a segunda observação é que, ele abre no firefox, mas no google chrome ele não abre.

EuclidesFilizola

Aqui ficou meu método

public void geraRelatorioPassandoListaDeObjetos(ActionEvent event) throws ClassNotFoundException, SQLException, JRException, IOException {

			

		// Conexão com o banco para o segundo relatório

		this.criaConexao();

		conexao = getConexao();

		

		// criação dos parametros

		Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();

		

		

		// conexão com o banco que será utilizada pelo subrelatório

		map.put("REPORT_CONNECTION", conexao);

		//map.put("IMAGE",diretorioReal+"/images/loma.jpg");

		

		// pego o caminho do diretório onde se encontra o subrelatório

		

		//map.put("SUBREPORT_DIR", getDiretorioReal("/pages/relatorios/relatorios/"));

		

		ArrayList&lt;Abastecimento&gt; relatorio =  new ArrayList&lt;Abastecimento&gt;(); 

			

		relatorio = (ArrayList&lt;Abastecimento&gt;) abastecimentoService.retrieveAll();

			

			//getListaAlunos(conexao);

		

		JRBeanCollectionDataSource ds = new

		JRBeanCollectionDataSource(relatorio);

		

		

		/*

		* Mando o jasper gerar o relatório. Nesse caso passo o map,

		* já que ele tem dois parâmetros que serão utilizados

		*/

		

		

		  

		FacesContext context = FacesContext.getCurrentInstance();  

		  

		HttpSession session = (HttpSession) context.getExternalContext().getSession(false);  

		HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();  

		  

		String diretorioReal = session.getServletContext().getRealPath("");  

		  

		String caminhoRelatorio = diretorioReal+ "/pages/relatorios/relatorios/RelatorioAbastecimento.jasper";  

	

		JasperPrint print = JasperFillManager.fillReport(caminhoRelatorio, map, ds);

		

		JasperExportManager.exportReportToPdfFile(print, diretorioReal+ "/pages/relatorios/relatorios/RelatorioAbastecimento.pdf");

		

		response.setContentType("application/octet-stream");

		

		response.setHeader("Content-Disposition", "attachment; filename=RelatorioAbastecimento.pdf");

		

		response.sendRedirect(context.getExternalContext().getRequestContextPath()

				 +

	                    "/pages/relatorios/relatorios/RelatorioAbastecimento.pdf");

		

		context.responseComplete();

		

		//	gerarRelatorio(caminhoRelatorio,print);

		

		//return "/RelatorioAbastecimento.pdf";

		}

E aqui está meu botão com evento

&lt;td style="padding-left:10px; padding-top:10px;"&gt;

				&lt;a4j:commandButton id="btnPesquisar" value="Pesquisar" actionListener="#{abastecimentoRelatorioBean.geraRelatorioPassandoListaDeObjetos}" styleClass="button" /&gt;

			&lt;/td&gt;

Dessa forma, o relatorio abre dentro do proprio navegador.

Abraços, e agradeço a atenção de todos.

javer

Pessoal,

Desculpem reabrir esse tópico mas vou pegar o gancho.

Alguém saberia uma forma de depois de chamar o relatório recarregar a página?

Tenho por exemplo uma lista de boletos que são impressos em PDF, preciso que logo em seguida a "lista" seja mostrada vazia para o usuário, e o único jeito que consigo pensar é gerar ele vazia e mostrar a tela novamente, uma vez que o botão de relatório não é chamado por Ajax.

Meu relatório é mostrado assim:
protected void gerarArquivo(byte[] bytes, String nomeAquivo) throws IOException {

		FacesContext facesContext = FacesContext.getCurrentInstance();

		HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
		ServletOutputStream servletOutputStream = response.getOutputStream();

		response.setContentType("application/pdf");
		response.setHeader("Content-Disposition", "attachment;filename=\"" + nomeAquivo + "\"");

		servletOutputStream.write(bytes);
		servletOutputStream.flush();
		servletOutputStream.close();
		facesContext.responseComplete();
	}
Criado 16 de abril de 2011
Ultima resposta 27 de out. de 2014
Respostas 24
Participantes 5