IReports , JasperReports e Geração do Relatório

Boa tarde a todos

Trabalho com o Oracle Reports ( Que é um saco ) e cansei de sofrer. Resolvi montar um relatório no JasperReports/iReports. Então para isto, fiz o download do IReports e desenvolvi um relatório simples. Ele acessa uma pequena tabela do banco e mostra as informações perfeitamente no preview do iReports. Após compilado tenho um arquivo .jasper gerado

Agora começam os problemas. Preciso de um servlet que faça a geração deste relatório no browser em HTML e também em PDF. Para isso criei um projeto Web e adicionei o jasperreports.jar em minhas bibliotecas do netbeans e nele comecei as minhas tentativas que até agora não tiveram sucesso.

Nas minhas pesquisas encontrei alguns códigos que passam um objeto Connection para esta geração. Nesta hora fiquei confuso, pois imaginei que no arquivo .jasper as configurações da conexão da estavam OK.

Alguém tem algo semelhante e pode me ajudar ? O que preciso fazer ?
Tenho uma certa experiência em java e por isso acredito que não vou dar tanto trabalho :wink:

Boa tarde,

Para tentar melhorar as informações do post, vejam abaixo:

1 - O Ambiente / Projeto do NetBeans segue na figura NetBeans 001.

2 - O Servlet responsavel por abrir o relatorio.jasper é este: Lembrando que ainda não entendo o porque da conexão, já que no relatório a conexão já foi criada.

try {

            conexao();

            
            //Seta o tipo de aplicação do relatório 
            response.setContentType("application/pdf");

            // Na variavel pathJasper ficara o caminho do diretório para os relatórios compilados (.jasper)
            pathJasper = getServletContext().getRealPath("/reports/") + "\\";

            //
            path = getServletContext().getRealPath("/");

            // Parametros do relatorio
            Map parameters = new HashMap();
            parameters.put("Title", "Danfe");

            // Carrega relatório
            JasperPrint print = JasperFillManager.fillReport(pathJasper + reportName + "." + reportType, parameters, conn);


            //exporta para pdf e exibe no browser sem criar um arquivo fisico em sua maquina
            JasperExportManager.exportReportToPdfStream(print, Stream);


            //define os cabecalhos do header
            response.setHeader("Pragma", "");
            response.setHeader("Cache-Control", "");
            response.setHeader("Expires", "");

            //Escreve o relatorio no response
            OutputStream saida = response.getOutputStream();
            Stream.writeTo(saida);
            response.setContentLength(Stream.size());
            saida.flush();
            saida.close();

            out.println(pathJasper + reportName + "." + reportType);


        } finally {
            out.close();
        }

3 - O erro mostrado no browser é este. Acho que este erro ocorre porque o relatório não está sendo gerado.



Oi Lucas,

Na verdade, a conexão que você configura no ambiente é só para o DataSource de testes. A query configurada fica dentro do relatório, mas a conexão não.
Quando você vai colocar para rodar seu relatório na aplicação, você precisa passar a conexão entendeu?

Não analisei seu código de escrita dos dados do pdf no OutputStream pq acho que seu problema é outro.

Acho que alguma excessão deve estar sendo lançada. Seria legal vc passar o stacktrace da excessão para a genet dar uma olhada.
Apenas oi .jar do jasperreports não é o suficiente. Recomendo que você inseria TODOS os .jar que vem na distribuição (são váários).
Se algum deles entrar em conflito com os que você já tem no projeto (duas versões por exemplo), mantenha a versão mais nova.

[]´s

lblanco, não conheço muito jasper,ireport, mais vô tentar ajuar com o pouco que eu sei.
Assim o Jasper tem algumas maneirar de obter as informações para o relatorio, uma delas é o proprio jasper conectar no banco e obter as informações, as outras o programa que irá usar o jasper terá que passar as informações para o jasper…

Eu não sei se o jasper gera o relatorio em HTML. nunca usei… mais deve ter algum geito

Exemplo de um relatorio que eu fiz a um tempo…

//neste relatorio o jasper recebe as informações e não conecta no banco..
List<RelatorioVO> lista = dao.list();
HashMap<String, Object> parameters = new HashMap...
JRBeanCollectionDataSource jrDs = new JRBeanCollectionDataSource(lista);
//posso passar um resultset no lugar do List ex: JRResultSetDataSource jrDs = new JRResultSetDataSource(dao.getRelatorioInResultSet());

JasperPrint jasperPrint = JasperFillManager.fillReport(this.getClass().getResourceAsStream("/pacote/relatorio.jasper", parameters, jrDs);

JRAbstractExporter exporter = new JRPdfExporter();//pdf
//JRAbstractExporter exporter = new JRXhtmlExporter();//xhtml nunca usei...
exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE, file);
exporter.exportReport();

Opa, obrigado galera !!!

Coloquei estas libs, mas o problema persiste. Antes de fazer funcionar , gostaria de entender.
O davidbuzatto ja me explicou questão da conexão, Agora resta saber porque o pdf nao gera :frowning:

commons-beanutils-1.8.2.jar
commons-collections-3.2.1.jar
commons-digester-1.7.jar
commons-logging-1.1.jar
iText-2.1.7.jar
jasperreports-3.7.5.jar
jdt-compiler-3.1.1.jar

Nenhuma excessão está sendo lançada?
O jasper precisa de muitas outras dependências além destas.

[]´s

Opa David, desculpe.
Ai vai o erro ! Qual será esta lib ? Eita rs.

06/10/2010 11:37:49 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Relatorio threw exception
java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1516)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1361)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        at net.sf.jasperreports.engine.util.JRLoader.<clinit>(JRLoader.java:60)
        at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:267)
        at Relatorio.processRequest(Relatorio.java:54)
        at Relatorio.doGet(Relatorio.java:89)

É a commons-logging.

Então Lucas, faz o seguinte, primeiro edita o título do seu tópico. Escrever em caixa alta é feio, parece que você está gritando.
Quanto às dependências, no pacote do jasper (no completo), vem todos os .jar que são necessários (são vááários).
Seu iReport provavelmente é da mesma versão do jasper que você está usando não é?
Dentro da instalação do iReport tem os .jars tbm.

[]´s

Ah, qual iReport vc ta usando? A versão standalone ou o plugin do NetBeans?

Prontinho, já alterei o título do post conforme você alertou.
Estou usando a versão standalone 3.7.5, acabei de baixar. Inclui mais libs e agora o erro é:

06/10/2010 17:15:08 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Relatorio threw exception
java.lang.ClassNotFoundException: org.codehaus.groovy.control.CompilationFailedException
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1516)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1361)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        at java.lang.Class.getDeclaredConstructors0(Native Method)
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
        at java.lang.Class.getConstructor0(Class.java:2699)
        at java.lang.Class.newInstance0(Class.java:326)
        at java.lang.Class.newInstance(Class.java:308)
        at net.sf.jasperreports.engine.JasperCompileManager.getCompiler(JasperCompileManager.java:472)
        at net.sf.jasperreports.engine.JasperCompileManager.loadEvaluator(JasperCompileManager.java:238)
        at net.sf.jasperreports.engine.fill.JRFillDataset.createCalculator(JRFillDataset.java:420)
        at net.sf.jasperreports.engine.fill.JRBaseFiller.<init>(JRBaseFiller.java:432)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:77)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:87)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:57)
        at net.sf.jasperreports.engine.fill.JRFiller.createFiller(JRFiller.java:142)
        at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:52)
        at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:417)
        at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:247)
        at Relatorio.processRequest(Relatorio.java:73)
        at Relatorio.doGet(Relatorio.java:129)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
        at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1555)
        at java.lang.Thread.run(Thread.java:619)

Bom, vou tentando por aqui.
Obrigado pelas dicas por enquanto.

Então Lucas, adiciona todos.
Dentro da instalação do iReport, dá uma olhada, deve ter uma pasta chama ext dentro da pasta modules e uma chamada libs.
Vc tem que copiar TODOS os .jar das duas pastas (ext e libs) e colocar no seu projeto.

É provável que seu relatório não vá usar todas elas, mas copie todas por precaução.
Como falei, se houver algum conflito (mesmo .jar de versões diferentes) opte pelo de versão mais nova (versão maior).

[]´s

libs:

xalan.jar

modules.ext

ant-1.7.1.jar antlr-2.7.6.jar asm-attrs.jar asm.jar barbecue-1.5-beta1.jar barcode4j-2.0.jar batik-anim.jar batik-awt-util.jar batik-bridge.jar batik-css.jar batik-dom.jar batik-ext.jar batik-gvt.jar batik-parser.jar batik-script.jar batik-svg-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar bcel-5.2.jar bsh-2.0b4.jar castor-1.2.jar cglib-2.1.jar cincom-jr-xmla.jar commons-beanutils-1.8.2.jar commons-collections-3.2.1.jar commons-dbcp-1.2.2.jar commons-digester-1.7.jar commons-javaflow-20060411.jar commons-logging-1.1.jar commons-math-1.0.jar commons-pool-1.3.jar commons-vfs-1.0.jar dom4j-1.6.jar ehcache-1.1.jar eigenbase-properties-1.1.0.10924.jar eigenbase-resgen-1.3.0.11873.jar eigenbase-xom-1.3.0.11999.jar ejb3-persistence.jar groovy-all-1.5.5.jar hibernate-annotations.jar hibernate-commons-annotations.jar hibernate3.jar hsqldb-1.8.0-10.jar iText-2.1.7.jar iTextAsian.jar jakarta-bcel-20050813.jar jasperreports-3.7.4.jar jasperreports-chart-themes-3.7.4.jar jasperreports-extensions-3.5.3.jar jasperreports-fonts-3.7.4.jar javacup.jar javassist-3.4.GA.jar jaxen-1.1.1.jar jcommon-1.0.15.jar jdt-compiler-3.1.1.jar jfreechart-1.0.12.jar jpa.jar js_activation-1.1.jar js_axis-1.4patched.jar js_commons-codec-1.3.jar js_commons-discovery-0.2.jar js_commons-httpclient-3.1.jar js_jasperserver-common-ws-3.5.0.jar js_jaxrpc.jar js_mail-1.4.jar js_saaj-api-1.3.jar js_wsdl4j-1.5.1.jar jta.jar jxl-2.6.jar log4j-1.2.15.jar mondrian-3.1.1.12687-Jaspersoft.jar olap4j-0.9.7.145.jar png-encoder-1.5.jar poi-3.5-FINAL-20090928.jar rex-20080421.jar rhino-1.7R1.jar saaj-api-1.3.jar slf4j-api.jar slf4j-log4j12.jar spring.jar sqleonardo-2007.03.jar swingx-2007_10_07.jar xml-apis-ext.jar xml-apis.jar

Remova as que você tem certeza que não vai usar (hibernate por exemplo).
Se vc testar depois que removeu algum .jar e não der certo, volte ele.

[]´s

Esta versão nova do JasperReports utiliza uma classe que não era utilizada em outras versões. Este exception é de uma classe que está faltando. Você encontra esta classe num jar que está onde vocês descompactou seu IReports. Procure o arquivo groovy-all-1.5.5.jar no caminho abaixo.

/iReport-3.7.5/ireport/modules/ext/groovy-all-1.5.5.jar

Este jar resolve o problema que apresenta no seu log.

David, acho que estamos chegando perto , ou não rs !

Coloquei todas as libs, seguindo as suas dicas e agora temos o seguinte, novo erro !

log4j:WARN No appenders could be found for logger (net.sf.jasperreports.extensions.ExtensionsEnvironment).
log4j:WARN Please initialize the log4j system properly.
java.lang.IllegalStateException: getWriter() has already been called for this response
        at org.apache.catalina.connector.Response.getOutputStream(Response.java:579)
        at org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:183)
        at javax.servlet.ServletResponseWrapper.getOutputStream(ServletResponseWrapper.java:102)
        at Relatorio.processRequest(Relatorio.java:86)
        at Relatorio.doGet(Relatorio.java:129)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
        at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1555)
        at java.lang.Thread.run(Thread.java:619)

Sabe o que pode ser ?

getWriter() has already been called for this response

Você está obtendo o writer do servlet mais de uma vez.
Use o método getWriter()/getOutpuStream() apenas uma vez.

[]´s

Pois é, li a mensagem de erro e procurei também duas chamadas para este método. Mas não consegui ver. O Código é;

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, JRException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {

            conexao();

            
            //Seta o tipo de aplicação do relatório 
            response.setContentType("application/pdf");

            // Na variavel pathJasper ficara o caminho do diretório para os relatórios compilados (.jasper)
            pathJasper = getServletContext().getRealPath("/reports/") + "\\";

            //
            path = getServletContext().getRealPath("/");

            // Parametros do relatorio
            Map parameters = new HashMap();
            parameters.put("Title", "Danfe");

            // Carrega relatório
            JasperPrint print = JasperFillManager.fillReport(pathJasper + reportName + "." + reportType, parameters, conn);


            //exporta para pdf e exibe no browser sem criar um arquivo fisico em sua maquina
            JasperExportManager.exportReportToPdfStream(print, Stream);


            //define os cabecalhos do header
            response.setHeader("Pragma", "");
            response.setHeader("Cache-Control", "");
            response.setHeader("Expires", "");

            //Escreve o relatorio no response
            OutputStream saida = response.getOutputStream();
            Stream.writeTo(saida);
            response.setContentLength(Stream.size());
            saida.flush();
            saida.close();



        } catch(Exception ex){
         ex.printStackTrace();
        } finally {
            out.close();
        }
    }

Pessoal,

Retirei a linha:

PrintWriter out = response.getWriter();

E Funcionou !!!

O Relatório agora é emitido em PDF no browser. Bom, agora preciso que ele seja gerado direto para a impressão sem abrir.
Vou iniciar as pesquisas e continuo neste tópico. Quando terminar vou fazer um tutorial e colocar aqui.

Abraços

Para salvar sem imprimir na tela basta mudar o header content-disposition de ‘inline’ para ‘attachment’

[quote=lblanco]Pessoal,

Retirei a linha:

PrintWriter out = response.getWriter();

E Funcionou !!! [/quote]

Era isso que eu tinha falado :smiley:
Que bom que deu certo.

[]´s