Ireport + jsf + primefaces + erro ao gerar relatorio - RESOLVIDO

Bom dia pessoal, tudo bom?
Pessoal estou tentando gerar um pdf utilizando o iReport.
Para desenvolver eu utilizei como exemplo o post http://www.guj.com.br/java/126468-ireport--jsf

Segue codigo

[code] public String rodarPdf(){
FacesContext facesContext = FacesContext.getCurrentInstance();

	facesContext.responseComplete();

	List<Aluno> listaFuncionario = new ArrayList<Aluno>();

	listaFuncionario = ControleFactory.getInstance()
			.getAlunoscontrole().listaTodos(2013);

	JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(
			listaFuncionario); 
    Map<String, Object> parameters = new HashMap<String, Object>();  
      
    String arquivo = new UtilFaces().getServletContext().getRealPath("/WEB-INF/cart.jasper");  
    File reportFile = new File(arquivo);  
    byte[] bytes = null;  
    try{  
        bytes = JasperRunManager.runReportToPdf(reportFile.getPath(), parameters, ds);  
        launchPdfShow(bytes,false,"none");
    }catch(JRException e){  
        e.printStackTrace();  
    }            
    
    return "";
}  

private void launchPdfShow(byte[] bytes,boolean isDownload,String fileName){
HttpServletResponse response = new UtilFaces().getResponse();
if (bytes != null && bytes.length > 0) {
ServletOutputStream ouputStream = null;
try {
response.setContentType(“application/pdf”);

            if(isDownload)  
                response.setHeader("Content-disposition", "attachment;filename="+fileName+".pdf");  

            response.setContentLength(bytes.length);  
            ouputStream = response.getOutputStream();  
            ouputStream.write(bytes, 0, bytes.length);  
            ouputStream.flush();  
            ouputStream.close();  
            new UtilFaces().getFacesContext().responseComplete();  
        } catch (IOException ex) {  
            ex.printStackTrace();  
        }  
     }  
}

public class UtilFaces {

public UtilFaces() {  
}  
  
public FacesContext getFacesContext() {  
    return FacesContext.getCurrentInstance();  
}  
public ExternalContext getExternalContext() {  
    return getFacesContext().getExternalContext();  
}  
public HttpServletRequest getRequest() {  
    return (HttpServletRequest) getExternalContext().getRequest();  
}  
public HttpServletResponse getResponse() {  
    return (HttpServletResponse) getExternalContext().getResponse();  
}  
public HttpSession getHttpSession(){  
    return (HttpSession) getFacesContext().getExternalContext().getSession(false);  
}  
public ServletContext getServletContext(){  
    return (ServletContext) getExternalContext().getContext();  
}  
public void msg(String destination,String msg){  
    FacesMessage message = new FacesMessage(msg);  
    getFacesContext().addMessage(destination, message);  
}  
public void addErrorMessage(Exception ex, String defaultMsg) {  
    String msg = ex.getLocalizedMessage();  
    if (msg != null && msg.length() > 0) {  
        addErrorMessage(msg);  
    } else {  
        addErrorMessage(defaultMsg);  
    }  
}  

public void addErrorMessages(List<String> messages) {  
    for (String message : messages) {  
        addErrorMessage(message);  
    }  
}  

public void addErrorMessage(String msg) {  
    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);  
    FacesContext.getCurrentInstance().addMessage(null, facesMsg);  
}  

public  void addSuccessMessage(String msg) {  
    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);  
    FacesContext.getCurrentInstance().addMessage("successInfo", facesMsg);  
}  

public  void addWarnMessage(String msg) {  
    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN, msg, msg);  
    FacesContext.getCurrentInstance().addMessage("warnInfo", facesMsg);  
}  

public  void addFatalMessage(String msg) {  
    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_FATAL, msg, msg);  
    FacesContext.getCurrentInstance().addMessage("fatalInfo", facesMsg);  
}  

}[/code]

Porem esta ocorrendo o seguinte erro:

[quote]Mar 05, 2013 10:57:02 AM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[//index.xhtml]
javax.el.ELException: /index.xhtml: java.lang.IllegalStateException: getWriter() has already been called for this response
at com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:88)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.facelets.compiler.UILeaf.encodeAll(UILeaf.java:183)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:424)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:124)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: getWriter() has already been called for this response
at org.apache.catalina.connector.Response.getOutputStream(Response.java:605)
at org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:197)
at escolaonline.ManagedBeans.CadLoginBean.launchPdfShow(CadLoginBean.java:279)
at escolaonline.ManagedBeans.CadLoginBean.rodarPdf(CadLoginBean.java:257)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:484)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:161)
at org.apache.el.parser.AstValue.getValue(AstValue.java:173)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
at com.sun.faces.facelets.el.ELText$ELTextVariable.writeText(ELText.java:227)
at com.sun.faces.facelets.el.ELText$ELTextComposite.writeText(ELText.java:150)
at com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:85)
… 25 more[/quote]

Por teste a chamada fiz atraves de um js ao iniciar a pagina

<script type="text/javascript"> function action() { var form = document.forms[0]; form.action = "#{cadloginBean.rodarPdf()}"; } </script>

Alguem sabe o que pode estar acontecendo?
Vlwww pessoal

[]s

Algum motivo pra você não estar usando o componente de download do PrimeFaces?

Fala ae Rodrigo, então cara eu só havia mexido com iReport a uns bons anos atras utilizando Struts e JSP.
P\ falar a verdade estão meio perdido em como fazer ele funfar nesse ambiente JSF + Primefaces, faz pouco tempo q estou trabalhando com ele.
Poderia me dar um exemplo de uma melhor forma de montar?
Posso utilizar qualquer componente … ferramente.
Vlwww

[]s

É muito simples na verdade. Veja o exemplo do showcase deles:

http://www.primefaces.org/showcase/ui/fileDownload.jsf

Se ainda tiver alguma dúvida após ver isso aí, pode perguntar

Show … vou dar uma olhada e a tare posto o resultado =)

Vlwwww Rodrigo.

[]s

Rodrigo, ele não reconhece o arquivo, seria isso?

InputStream stream = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getResourceAsStream("/WEB-INF/cart.jasper"); file = new DefaultStreamedContent(stream, "application/pdf", "cart.pdf");

O que esta errado ao pegar o jasper e criar o pdf?
Tem que ter algo nesse meio de campo certo?

Vlwww

[]s

Opa, tem sim. O arquivo Jasper é simplesmente o modelo do seu relatório, você precisa populá-lo e imprimí-lo no formato desejado. Ex:

InputStream inputStream = buscarArquivoJasper(); JRDataSource jrds = new JRBeanCollectionDataSource(itens); // Itens sendo a lista que popula seu relatório, caso tenha feito com javabeans JasperPrint print = JasperFillManager.fillReport(arquivo, params, jrds); //params é o Map<String, Object> de parâmetros byte[] dadosPdf = JasperExportManager.exportReportToPdf(print); InputStream relatorio = new ByteArrayInputStream(dadosPdf); file = new DefaultStreamedContent(stream, "application/pdf", "cart.pdf");

Fala Rodrigo … cara bateu na trave …

[code] public FileDownloadControllerBean() {

	HashMap parameters = new HashMap();

	
	try{
		
		FacesContext facesContext = FacesContext.getCurrentInstance();

		facesContext.responseComplete();

		List<Aluno> listaFuncionario = new ArrayList<Aluno>();

		listaFuncionario = ControleFactory.getInstance()
				.getAlunoscontrole().listaTodos(2013);			
		
		ServletContext scontext = (ServletContext) facesContext
				.getExternalContext().getContext();
		
		InputStream stream = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getResourceAsStream("/WEB-INF/cart.jasper");    
		JRDataSource jrds = new JRBeanCollectionDataSource(listaFuncionario); // Itens sendo a lista que popula seu relatório, caso tenha feito com javabeans  
		JasperPrint print = JasperFillManager.fillReport(stream, parameters, jrds); //params é o Map<String, Object> de parâmetros  
		byte[] dadosPdf = JasperExportManager.exportReportToPdf(print);  
		InputStream relatorio = new ByteArrayInputStream(dadosPdf);  
		file = new DefaultStreamedContent(stream, "application/pdf", "cart.pdf");    		
 
	}catch (Exception e) {

		e.printStackTrace();

	}
	
}[/code]

Peço desculpa se fiz alguma burrice … mas to meio enferrujado com irepor.
Vlwwww

[]s

Você não precisa de um bean só pra isso, muito menos manipular o estado do ciclo de vida, tente fazer algo mais simples, um método que retorna o StreamedContent e pronto.public StreamedContent imprimirRelatorio(){ // Busca o relatório onde precisar byte[] dadosPdf = JasperExportManager.exportReportToPdf(print); InputStream relatorio = new ByteArrayInputStream(dadosPdf); return new DefaultStreamedContent(stream, "application/pdf", "cart.pdf"); }

Fala Rodrigo … deu certo cara.

[code] public StreamedContent getSampleReportPDF() {

    InputStream relatorio = null;  

    try {  

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

        ByteArrayOutputStream Teste = new ByteArrayOutputStream();  

        
		InputStream stream = ((ServletContext) FacesContext
				.getCurrentInstance().getExternalContext().getContext())
				.getResourceAsStream("/WEB-INF/cart.jasper");
        
       

		List<Aluno> listaFuncionario = new ArrayList<Aluno>();

		listaFuncionario = ControleFactory.getInstance().getAlunoscontrole()
				.listaTodos(2013);                

        JRBeanCollectionDataSource datasource = new JRBeanCollectionDataSource(listaFuncionario);  
        HashMap<String, Object> params = new HashMap<String, Object>();  
        JasperPrint print = JasperFillManager.fillReport(stream, 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(FileDownloadController.class.getName()).log(Level.SEVERE, null, ex);  
    }  

    return new DefaultStreamedContent(relatorio);  


}[/code]

<p:commandButton rendered="true" id="exportar1" value="PDF" ajax="false"> <p:fileDownload value="#{fileDownloadController.sampleReportPDF}" /> </p:commandButton>

Muito obrigado pela força.

[]s

Opa, sem problemas! :slight_smile: Que bom que conseguiu.

Eu lembro que apanhei um pouco no começo também, mas o PrimeFaces faz a maior parte do trabalho :slight_smile: