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
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.
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.
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();
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
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)
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.
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).
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.
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)
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.