Tutorial: Técnicas de Geração de Relatórios com JasperReports / iReport
Uma abordagem utilizando a ferramenta de design iReport
Por diversas vezes tenho me deparado com pessoas no CEJUG e em diversos fóruns Java com dificuldades na geração de relatórios com o JasperReports ou na utilização do iReport como ferramenta visual de diagramação dos documentos.
Foi então que tive a idéia de disponibilizar esse tutorial no meu blog que mostra como criar relatórios no iReport através de três técnicas: passando uma conexão com o banco de dados, passando um ResultSet (encapsulado na classe JRResultSetDataSource) e passando uma lista de objetos (encapsulada na classe JRBeanCollectionDataSource).
Além da demostração de como gerar os relatórios, mostro também o código Java correspondente de cada método, dou algumas dicas para modificar os textFields dos relatórios e outras de utilização do próprio iReport.
Resolvi também disponibilizar a aplicação que criei em JSF no formato zip e war. Bom proveito a todos.
Clique aqui para baixar o PDF do tutorial.
Clique aqui para baixar o projeto do Eclipse compactado (zip).
Clique aqui para baixar o projeto no formato war.
Agora da para ter uma boa noção de como iniciar os estudos com IReport, tenho certeza que será de grande valia para muitas pessoas que necessitam criar relatórios.
Fiquei feliz que em seu primeiro post, você veio com todas as forças e poderes, para demonstrar um conteúdo tão necessário.
Esta de Parabens.
Ythalo, obrigado pelo seu comentário. O desafio agora é continuar atualizando o conteúdo.
Parabéns pela iniciativa Pablo! Gostei do tutorial!
Oi Loiane. Dei uma olhada no seu site também. Muito legal. Parabéns pela formatura.
Excepcional!!!!!!!!
Muito obrigado!
Que bom ter pessoas que compartilham seus conhecimentos
Olá Pablo, realmente dos materiais que conheço este é o mais atual e também o mais completo. Estou tentando aplicar a meu projeto mas tenho um erro. Vou postar aki para você me dar uma dica.
Segue:
private String getContextPath() {
HttpSession session = (HttpSession)
FacesContext.getCurrentInstance().getExternalContext().getSession(false);
return session.getServletContext().getContextPath();
}
A linha return session.getServletContext().getContextPath(); acusa erro no método getContextPath(). E o eclipse pede para eu fazer a seguinte modificação:
return ((RelatorioUsuario) session.getServletContext()).getContextPath();
Só que quando eu rodo o projeto uma exceção é lançada em tempo de execução:
java.lang.ClassCastException: org.mortbay.jetty.servlet.Context$SContext cannot
be cast to br.com.projetobase.report.RelatorioUsuario
at br.com.projetobase.report.RelatorioUsuario.getContextPath(RelatorioUs
uario.java:104)
at br.com.projetobase.report.RelatorioUsuario.preenchePdf(RelatorioUsuar
io.java:79)
at br.com.projetobase.report.RelatorioUsuario.geraRelatorio(RelatorioUsu
ario.java:38)
at br.com.projetobase.bean.UsuarioBean.relatorioGeral(UsuarioBean.java:3
22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Eu entendo que não da para converter uma String retornada em um UsuarioBean, como posso resolver isto?
Olá Anderson. O método getContextPath serve para retornar o nome da aplicação no container e ajuda a encontrar o local do relatório na aplicação.
O erro do seu projeto é que deve estar sendo realizado um import incorreto.Isso pode ser verificado pelo trace da exception, onde diz que org.mortbay.jetty.servlet.Context não pode ser convertido em RelatorioUsuario. Na verdade, esse método getServletContext é para retornar um ServletContext, do pacote javax.servlet.
O que você deve fazer é tirar esse cast e verificar se a classe HttpSession utilizada no método é do pacote javax.servlet.http.
Qualquer coisa, pode escrever no meu e-mail que fica melhor: pablonobrega2004@gmail.com
Abraço.
Pablo funcionou sim, mas não foi o pacote errado e sim a lib do pacote javax.servlet q estava errado. É pra ser a versão 2.5 e estava a 2.4.
Grato!
kem pode ajudar s.f.f.
tenho o seguinte código para gerar o relatório na minha aplicação e o rela´torio só vem com o cabeçalho.
código:
long start = System.currentTimeMillis();
Map hm= new HashMap();
java.io.InputStream is = JRLoader.getLocationInputStream(“c:\\reports\\northwind.xml”);
Document document = JRXmlUtils.parse(is);
hm.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, document);
hm.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, “yyyy-MM-dd”);
hm.put(JRXPathQueryExecuterFactory.XML_NUMBER_PATTERN, “#,##0.##”);
hm.put(JRXPathQueryExecuterFactory.XML_LOCALE, Locale.ENGLISH);
hm.put(JRParameter.REPORT_LOCALE, Locale.US);
JasperFillManager.fillReportToFile(“c:\\reports\\CustomersReport.jasper”, hm);
System.err.println(“Tempo de preechimento : ” + (System.currentTimeMillis() – start));
JasperExportManager.exportReportToPdfFile(“c:\\reports\\CustomersReport.jrprint”);
System.err.println(“Tempo de geração do PDF : ” + (System.currentTimeMillis() – start));
agradecia a ajuda pois estou já desesperado
obrigado
Pessoal, baixei o arquivo compactado e importei no eclipse, corrigi o import das libs do apache, só que não está abrindo a página. Erro 404.
Alguem pode ajudar??
Agradeço.
Olá Kleber. Corrigi algumas coisas no projeto e agora se você baixar novamente vai dar certo. É que aqui na minha máquina meu Tomcat tinha uns jar’s a mais. Não esqueça de criar a base de dados no MySQL para poder simular a passagem dos dados para o JasperReports. O script de criação está no próprio projeto, na pasta ‘script_banco’. O banco deve se chamar academico. Qualquer dúvida, pode entrar em contato.
Olá Pablo, tudo bem ?
Pablo, estou com um erro louco e não encontro saída. Verifique seu tutorial e não tem exemplo sobre EJBQL. Veja, criei um relatório com EJBQL e quando chamo o relatório recebo as exceções abaixo:
net.sf.jasperreports.engine.JRException: Error retrieving field value from bean :
e
Caused by: java.lang.NoSuchMethodException: Unknown property ” on class ‘class pojo.Cliente’
Na última dá para ver que parece que ele tem no relatório um campo vazio, mas procurei por este campo no xml do relatório e não encontrei..
Poderia me ajudar?
Abraços e obrigado
Olá Everton. Uma possível causa para o problema é você estar usando o jar errado na sua aplicação. Por exemplo: você pode ter criado o seu relatório na versão 3.7.1 do iReport e está usando o jar do jasperreports da versão 3.0. Um detalhe: nas últimas versões, o jasper reports precisa do jar do Groovy, que pode ser obtido no próprio diretório do iReport.
Abraço.
Muito bom tutorial Pablo.
Rapadura do ceará e foda deixa o cara potente ! parabéns UECE só tem fera !
pessoal quero uma ajuda,sou novato em java e queria saber o inicio desse código pq estou sofrendo muito atrás de tutoriais que ensine a gerar relatório eu pesso 100000000… ajuda.
Obrigado pela atenção
Qual é a sua dúvida exatamente, Rauan? Posso tentar te ajudar.
Olá Pablo, Gostei muito do seu Tutorial mas estou com dificuldades de fazer o projeto funcionar. Está apresentando um erro do import do HttpSession. Será que está faltando algum driver?
Eduardo, o seu projeto é Desktop ou Web? A apostila é baseada em JSF. Se o seu projeto for Struts, Desktop ou JSP+Servlets, a forma de você conseguir o diretório onde está algum recurso (executada pelo método getDiretorioReal(String diretorio)) e de conseguir o contexto (executada pelo método getContextPath()) é diferente. Responde aí que eu posso te ajudar a substituir esses códigos. Abraço.
olá Pablo, sou iniciante no ireports e tenho uma duvida, estou fazendo um relatório que tem dois subs nele. só que esses subs podem ou não ter valores, mas eu gostaria que mesmo que não tivesse que eles aparecessem, vc poderia me dar uma sugestão?
Oi Leiliane. Nesse caso, acho que a melhor opção é passar um parâmetro do relatório principal para o subrelatório e exibí-lo nesse subrelatório. Você pode passar, por exemplo, uma String com o cabeçalho do subrelatório.
Olá Pablo.
Eu criei um parâmetro no meu relatório master com o titulo do meu subrelatório
quando eu coloquei o sub no master eu disse que o parametro nele era o mesmo que o master.Mas não funcionou!
hehe
estou fazendo algo de errado?
se o sub tiver valores ele funciona, se não tiver não funciona. =/
grata desde já
Leiliane
Muito bom o material!
Me responde uma pergunta, o que é mais rápido?Fazer o relatório passando objeto ou passando a conexão e deixando o relatório executar a query?
Obrigado.
Passando a conexão normalmente é mais rápido. Mas isso é bem relativo. Se você já tiver, por exemplo, o objeto já carregado em memória e apenas passá-lo para o relatório, provavelmente será mais rápido do que abrir conexão com o banco, fazer a consulta e preencher o relatório.
Muito bom o tutorial !Parabens!