Parte 1 – Parte 2 – Parte 3 – Parte 4 – Parte 5
Olá a todos! Nesta quinta e última parte do nosso tutorial, iremos aprender a como usar os nossos relatórios em um projeto Web. Esse parte do tutorial vai ser rápida, pois já temos praticamente tudo o que precisamos. Primeiro gostaria de pedir para quem não está acompanhando o tutorial, que baixe o projeto finalizado na Parte 4 clicando aqui. Iremos criar um novo projeto no NetBeans, só que agora do tipo Web e vamos configurá-lo com base no que já fizemos no nosso projeto original. Vamos lá então!
No NetBeans, vá em File -> New Project. No assistente de criação de projetos, escolha “Java Web” na lista de categorias e na lista de tipos de projetos, escolha “Web Application”. Clique em “Next”. Em “Project Name” dê o nome do projeto. Eu sugiro “TutorialRelatoriosWeb” (sem as aspas). Em “Project Location” escolha onde o projeto vai ser salvo. Eu vou deixar na mesma pasta do projeto original. Marque a opção “Use Dedicated Folder for Storing Libraries” e deixe o valor padrão (.\lib). Se quiser, marque a opção “Set as Main Project”. Clique em “Next”.
No próximo passo, onde é configurado o servidor que a aplicação vai ser executada, eu vou deixar o Tomcat escolhido. Se vocês preferirem usar outro servidor, não tem problema, basta selecioná-lo na lista. Deixe desmarcada a opção “Use dedicated library folder for server JAR files”. Em “JavaEE version”, deixe escolhida a versão padrão, pois não precisamos nos preocupar com isso no nosso projeto de testes. No meu caso, ficou selecionado Java EE 5. Em “Context Path” deixe o valor sugerido. No meu caso, é “/TutorialRelatoriosWeb”. Como não vamos usar nenhum framework MVC, você já pode clicar em “Next”. Feito isso, o projeto será criado e será aberto no NetBeans.
Com o projeto criado, acesse suas propriedades clicando com botão direito na raiz do projeto e escolhendo a opção “Properties”, que é a última da lista. Em “Categories” procure pelo item “Run” e selecione-o. Desmarque a opção “Deploy on Save” para evitar que seja feito um deploy a cada vez que salvarmos algo do nosso projeto. Já que estamos aqui, vamos aproveitar para configurar as bibiliotecas. Não vou colocar as figuras desse processo, pois já foi explicado nas primeiras partes do tutorial.
Selecione o item “Libraries” na lista de categorias e clique no botão “Add Library”. Primeiro vamos importar o driver do MySQL que vamos utilizar. Na janela que foi aberta, clique no botão “Import”. Procure pela biblioteca “MySQL JDBC Driver”, selecione-a e clique no botão “Import Library”. A biblioteca vai ser importada e aparecerá na janela anterior, mas ela ainda não foi inserida no projeto. Antes de a inserirmos, vamos criar a biblioteca do JasperReports. Para isso, clique no botão “Create…”. Em “Library Name” entre com o valor “JasperReports-3.7.5” (sem as aspas) e clique em “OK”. Note que eu vou manter a versão do JasperReports utilizado nas partes anteriores do tutorial, sendo assim sua versão pode variar dependendo de quando você estiver seguindo esse tutorial, visto que novas versões do JasperReports são lançadas frequentemente. Se a versão que você estiver usando for mais nova, vamos dizer, 3.7.6, defina um nome da biblioteca que reflita a versão utilizada, ou seja “JasperReports-3.7.6”.
Feito isso, a janela “Customize Library” será exibida. Clique no botão “Add JAR/Folder”. Como já fizemos isso uma vez nas partes anteriores do tutorial, o projeto original já tem essa biblioteca configurada com os JARs necessários. Então vamos usá-los. Procure pela pasta do projeto original (TutorialRelatorios). Dentro dela, entre na pasta “lib”. Dentro da pasta “lib”, existirá uma pasta chamada “JasperReports-3.7.5”. O número da versão pode variar de acordo com a sua versão. Entre nela, selecione todos os JARs e clique no botão “Add JAR/Folder”. O NetBeans vai perguntar se você quer criar um diretório com o nome da biblioteca dentro da pasta “lib” do projeto atual (TutorialRelatoriosWeb). Diga que sim e os JARs serão listados na janela “Customize Library”. Clique em OK.
Novamente a janela “Add Library” será exibida, agora contendo a também a biblioteca do JasperReports que acabamos de configurar. Selecione tanto a biblioteca do JasperReports quanto a biblioteca do MySQL e clique no botão “Add Library”. Agora as bibliotecas serão adicionadas no projeto.
Ainda na janela de propriedades, procure a categoria “Sources” (primeira) e selecione-a. Vamos criar agora o diretório onde guardaremos os nossos fontes do relatório. Na tabela “Source Package Folders”, clique no botão “Add Folder…”. Serão exibidas os diretórios contidos no projeto. Crie então uma nova pasta, chamada “relatorios” (sem acentos e sem aspas), selecione-a e clique em “Open”. A pasta será referenciada na tabela. Clique duas vezes na célula correspondente à coluna “Label” da pasta, preencha com “Relatórios” (sem as aspas) e tecle <ENTER> para trocar o “Label” da pasta. Esse “Label” vai ser utilizado para mostrar a pasta de relatórios na árvore do projeto.
Estamos quase lá. Por fim, ainda na janela de propriedades, selecione a categoria “Packaging”, dentro da categoria “Build”. Em “Exclude From WAR File”, adicione uma vírgula e o valor “**./*.jrxml” (sem as aspas). Isso fará com que os nossos arquivos fonte de relatórios não sejam empacotados no arquivo WAR. O valor final do campo deve ficar assim: “**/*.java,**/*.form, **/*.jrxml” (sem as aspas). Pronto! Clique em OK na janela de propriedades e aguarde o NetBeans escanear as novas configurações do projeto.
Agora, abra o projeto anterior, vá na pasta de “Relatórios” dele, copie o arquivo “ClientesPorNome.jrxml” e cole na pasta “Relatórios” do novo projeto. Ainda não feche o projeto anterior. No projeto atual, abra o relatório que foi copiado e faça um Preview dele para ver se está tudo ok. Lembre-se que o datasource correto (Sakila – JDBC) tem que estar selecionado lá na barra de ferramentas do NetBeans. Se o relatório for renderizado e os dados aparecerem é porque está tudo ok.
Até agora nenhuma novidade. Criamos e configuramos o novo projeto e copiamos e testamos o arquivo de relatório que já fizemos para o novo projeto. Agora vamos às novidades.
Vamos criar um Servlet que vai ser responsável em pegar os possíveis dados do request que serão usados como parâmetros para os relatórios e invocar o JasperReports para criar o relatório. O funcionamento é parecido com o que fizemos no nosso programa desktop, entretanto agora não iremos mais criar um JFrame para exibir os relatórios, pois estamos usando um navegador não é mesmo? O que o nosso Servlet vai fazer é criar diretamente um arquivo .pdf do relatório e mandar exibir no navegador – caso haja algum plugin para leitura de PDF instalado – ou então o navegador vai sugerir que você faça o download do arquivo gerado.
Em “Source Packages”, crie três pacotes: “tutorialrelatoriosweb.jdbc”, “tutorialrelatoriosweb.servlets” e “tutorialrelatoriosweb.util” (todos sem as aspas). Vá no projeto anterior, no pacote “tutorialrelatorios.jdbc”, copie a classe ConnectionFactory e cole no pacote “tutorialrelatoriosweb.jdbc” do novo projeto. Se quiser, feche o projeto anterior. Agora no novo projeto, vá na pasta “tutorialrelatoriosweb.util” e crie uma classe com o nome de “ReportUtils” (sem as aspas). Ainda não vamos implementar nada nela. Feito isso, clique com o botão direito no pacote “tutorialrelatoriosweb.servlets”, vá em New -> Servlet. Se a opção Servlet não estiver sendo exibida, selecione “Other” e em “Categories” selecione “Web” e em “File Types” escolha “Servlet” e clique em “Next”.
O assistente para criar um novo Servlet será exibido. Em “Class Name” preencha com “ReportServlet” (sem as aspas) e clique em “Next”. Tanto “Servlet Name” quanto “URL Pattern” vão ser deixados da forma que o NetBeans sugeriu, ou seja, “ReportServlet” e “/ReportServlet” respectivamente. Clique em “Finish”.
O NetBeans vai gerar por padrão uma implementação padrão do método processRequest(…). Faça com que o seu fique assim:
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { OutputStream out = null; // aqui nós geramos o relatório... if ( out != null ) { out.close(); } }
Note que ainda não implementamos o método processRequest(…). Da mesma forma que fizemos no projeto anterior, vamos agora criar um método utilitário na classe ReportUtils que vai ser responsável em gerar o relatório. Segue a implementação comentada da classe ReportUtils.
tutorialrelatoriosweb.util.ReportUtils.java
package tutorialrelatoriosweb.util; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.sql.Connection; import java.util.Map; import javax.servlet.http.HttpServletResponse; 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.export.JRPdfExporter; /** * Classe com métodos utilitários para gerar relatórios. * * @author David Buzatto */ public class ReportUtils { /** * Gera o relatório em PDF. * * @param inputStream InputStream que contém o relatório. * @param parametros Parâmetros utilizados pelo relatório. * @param conexao Conexão utilizada para a execução da query. * @param response HttpServletResponse que será usado como base para * gerar o relatório. * @return O OutputStream do HttpServletResponse passado. * @throws JRException Caso ocorra algum problema na geração do relatório. * @throws IOException Caso ocorra algum problema na obtenção do * OutputStream. */ public static OutputStream createPDFReport( InputStream inputStream, Map<String, Object> parametros, Connection conexao, HttpServletResponse response ) throws JRException, IOException { // configura o content type do response response.setContentType( "application/pdf" ); // obtém o OutputStream para escrever o relatório OutputStream out = response.getOutputStream(); /* * Cria um JasperPrint, que é a versão preenchida do relatório, * usando uma conexão. */ JasperPrint jasperPrint = JasperFillManager.fillReport( inputStream, parametros, conexao ); // Exporta em PDF, escrevendo os dados no output stream do response. JRExporter exporter = new JRPdfExporter(); exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint ); exporter.setParameter( JRExporterParameter.OUTPUT_STREAM, out ); // gera o relatório exporter.exportReport(); // retorna o OutputStream return out; } }
Como vocês podem perceber, o método createPDFReport(…) da classe ReportUtils gera um relatório em PDF e o escreve no OutputStream do response do Servlet. Caso vocês queiram outros tipos de exportação, basta mudar o tipo do exportador. Clicando aqui, vocês podem ver a documentação da interface JRExporter e de todas as classes que a implementam. Note que ao mudar o exportador, você também precisa alterar o content type do response para refletir o tipo de arquivo gerado.
Vamos agora atualizar o nosso Servlet. O método processRequest(…) vai ficar assim:
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { OutputStream out = null; // obtém o relatório compilado InputStream inputStream = getClass().getResourceAsStream( "/ClientesPorNome.jasper" ); // preenche o mapa de parâmetros Map<String, Object> parametros = new HashMap<String, Object>(); parametros.put( "primeiroNome", "D%" ); try { // gera o relatório e atribui o OutputStream gerado out = ReportUtils.createPDFReport( inputStream, parametros, ConnectionFactory.getSakilaConnection(), response ); } catch ( SQLException exc ) { exc.printStackTrace(); } catch ( JRException exc ) { exc.printStackTrace(); } finally { // se não aconteceu nenhum problema, fecha o output stream if ( out != null ) { out.close(); } } }
Com isso feito, rode a aplicação e aponte o navegador para o endereço “http://localhost:8084/TutorialRelatoriosWeb/ReportServlet” (sem as aspas). Por padrão o Tomcat usado em desenvolvimento no NetBeans roda na porta 8084. Certifque-se que o seu está rodando nesta porta e se não estiver, use a porta correta. Se você seguiu corretamente o tutorial até aqui, será gerado então um .pdf com todos os clientes que tenham o primeiro nome iniciando com a letra “D” (veja o parâmetro “primeiroNome” passado para o relatório).
Note que agora, para passar parâmetros para o relatório, basta você obter os parâmetros pelo request e então adicionar os parâmetros desejados no mapa de parâmetros do relatório. Se quiser outros tipos de exportação, por exemplo, para Excel, basta criar um novo método na classe ReportUtils, que configura o content type apropriado (“application/ms-excel”) e o exportador necessário (JRXlsExporter ou JRXlsxExporter). Tanto a passagem de parâmetros quanto a geração de outros tipos de arquivos ficam como exercício para vocês. O Servlet ReportServlet pode ser generalizado também, permitindo que o nome do arquivo do relatório a ser gerao seja passado via request :).
Com isso terminamos nosso tutorial sobre relatórios em Java! Espero que tenham gostado! Para baixar o projeto criado nesta parte, clique aqui. Nos próximos tutoriais iremos aprender a usar a biblioteca JavaScript jQuery, que é extremamente útil e facilita muito a nossa vida.
Então é isso pessoal! Grande abraço a todos! Até a próxima 😉
Cara muito bom seus tutoriais li todos dessa serie de 5, estava com um problema no meu projeto que nem meus professores do curso conseguiram resolver, e graças as suas dicas de configuração la no primeiro tuto ja resolvel tudo
forte abraço
Oi Bruno,
Fico feliz que tenha te ajudado!
Abraço!
David, gostaria parabenizar pelo tutorial,
Já tinha mexido muito com JasperReport e iReport, isso a 1 ano atrás, mas esqueci tudo! principalmente configurar o classpath com os builds/classes para adicionar os fields no relatório. PQ uso JRBeanCollection, ai passo a classe e corro pro abraço. e achei no seu blog. Muito bom.
Obrigado.
Oi Daniel,
Fico feliz que tenha te ajudado!
Abraço!
David
nesse projeto na classe ConnectionFactory vc comenta o seguinte catch (
/*
* Como log usaremos o stacktrace das excessões, mas recomendo
* que para um projeto real você utilize algum mecanismo de log
* melhor, como o Log4J por exemplo.
*/)
Qual a dúvida?
Desculpa enviei sem querer
mas continuando… me surgiu a duvida de como configurar o log4j, pq realmente ele lança na saida a seguinte linha
log4j:WARN No appenders could be found for logger (net.sf.jasperreports.extensions.ExtensionsEnvironment).
log4j:WARN Please initialize the log4j system properly.
ja tentei tudo qeu aprendi ate agora no meu curso e em outros tutoriais mais nada deu certo
abraços
Então Bruno,
Eu falei do Log4J na classe de conexão no caso de você configurar um Logger que vai ser usado dentro da aplicação e não o logger para o JasperReports.
O Logger do Jasper não precisa ser configurado.
[]´s
Entendi muito obrigado pela atenção
bom para resolver esses warns
log4j:WARN No appenders could be found for logger (net.sf.jasperreports.extensions.ExtensionsEnvironment).
log4j:WARN Please initialize the log4j system properly.
eu fiz o seguinte ve se e o certo pelo menos deu certo aqui
no classpath da projeto criei um arquivo chamado log4j.properties com o seguinte conteudo
e no Main.java fiz as seguintes importações
e no metodo main
ai quando rodo o relatorio aqueles WARNS não aparecem mais
essa e a maneira correta???
Oi Bruno,
É isso mesmo. Você só precisa configurar agora os appenders. Vc não precisa ter necessariamente 2 appenders.
[]´s
Olá David
gostaria de lhe parabenizar pelo seu blog, em especial pelo tutorial de IReport que está
muito completo e didático, mais até que muitos livros que circulam por aí.
E aproveitando, gostaria de que vc, se puder, me ajude numa dúvida:
tenho um relatório de posição financeira que consiste em um relatório mestre com os dados do cliente e nele um subrelatório com as parcelas em aberto deste cliente.
Preciso que quando NÃO haja nada em aberto do cliente(subrelatorio vazio) não apareça os dados do cliente no relatorio mestre.
Eu fiz aqui usando a banda No Data(aparece os dados do cliente e abaixo uma mensagem de dados nao encontrados), mas para economia de papel gostaria que não aparecesse nem os dados do cliente no relatorio mestre.
Ex: para relatorio de todos os clientes quero que somente mostre os clientes com alguma parcela em aberto.
Se puder me ajudar eu agradeço muito.
Abraço!!
Oi Jonival,
Primeiramente, obrigado! Fico feliz que tenha gostado.
Em relação a sua dúvida, sinceramente não sei como fazer. Precisaria dar uma olhada e fazer uns testes, mas infelizmente estou sem tempo 😦
Se encontrar a solução, poste um novo comentário tudo bem?
Abraço!
Olá Davi
Parabéns pelo artigo. Você tem algum exemplo de uma aplicação JSF? Na verdade, preciso da classe bean.
Mais uma vez parabéns
Oi Alex,
Obrigado! Infelizmente não tenho. Não mexo com JSF já fazem uns 4 anos.
[]´s
Buzatto,
vc esta de parabéns. Nao sabia nada de ireport e agora to craque!! ahahah.
Excelente seu tutorial.
[]’s
Oi Marcelo,
Obrigado! Que bom que o tutorial foi útil.
[]´s
Parabéns, excelente!
Muito útil!
Oi Reinaldo, muito obrigado!
[]’s
Muito bom o tutorial, mas estou com o um problema que espero que tenha algum tipo de soluçao, toda vez que mando fazer a geraçao do meu relatorio, acontece o seguinte erro:
“cannot assign instance of net.sf.jasperreports.engine.base.JRBaseLine to field net.sf.jasperreports.engine.base.JRBasePen.penContainer of type net.sf.jasperreports.engine.JRPenContainer in instance of net.sf.jasperreports.engine.base.JRBasePen”
Sabe me dizer o que pode ser?? Preciso de uma luz, desenvolvo em JSF.
Obrigado!
Olá,
Vc tentou refazer o seu relatório? Parece que você está usando algum componente de desenho (retângulo, elipse, etc) e o tipo dele está errado… Tente verificar isso.
[]’s
Cara, parabéns pelos tutoriais! Estão me ajudando muito!!!
Muito Obrigado!
Que bom Jurandir!
[]’s
Muito obrigado! graças a você não tenho mais problemas com o ireport, agora também posso repassar esse novo conhecimento.
Que bom Rafael!
Eu que agradeço!
[]’s
Valeu David!!!
Ótimo tutorial, explicativo e sem dúvidas muito bom para o aprendizado de quem tem interesse no assunto.
David Parabéns meu caro. Apesar de ter conseguido todo meu objetivo no seu 2º tutorial, estava tão gostoso e simples de ler, que minha curiosidade me fez ler até o ultimo e não me arrependo. Muito bem explicado, muito bem escrito… simplesmente fantástico, o mundo precisa mais de pessoas como você que facilita as coisas, não alguns “colegas” que nos mandam link da documentação do java e diz que ajudou! E principalmente, parabéns ao seu cuidado com os comentários você responde a todos, achei isso fantástico.
Felicidades nesse 2012, muito sucesso!
Oi Francisco,
Obrigado pelos elogios. Tento responder a maioria dos comentários, mas quando os leitores querem tirar dúvidas eu infelizmente não tenho tempo de responder.
[]’s
David, seus tutoriais me ajudaram muito. Obrigado.
Que bom!
Eu que agradeço!
[]’s
Olá David, muito bom seu tutorial. Meu relatórios estavam de ‘frescuras’ comigo pois a forma que configurei não estava lá essas coisas; Parabéns, um forte abraço.
David,
Parabéns pelo artigo.
Baseado no seu artigo consegui montar meu ambiente mesmo usando a versão 4.6 do jasper.
Que bom Victor! Realmente as mudanças são muito poucas quando mudam as versões do NetBeans e do JasperReports, ainda mais que são exploradas nos tutoriais apenas as funcionalidades básicas das ferramentas
[]’s
Parabéns, David, o artigo e show de bola, funcionou beleza aqui.
Obrigado Evaldo!
[]’s
Excelente artigo David Buzatto. Fiz proveito das partes 1 a 4. A parte 5 ainda não, pois o meu projeto era em java swing.
Entretanto, eu realmente estou escrevendo não para falar sobre este excelente artigo, mas sim para agradecer pela enorme ajuda que me deste. Melhor, ajuda não, grande contribuição para o sucesso de um projeto de estágio na faculdade. Sinceramente, de coração, MUITO OBRIGADO MESMO. Espero que continue com mais artigos de grande qualidade como este. Você foi, indiretamente, de grande importância nesta parte da minha formação como também na ampliação dos meus conhecimento em Java. Em outras palavras eu aprendi a usar iReport/JasperReport.
Mais uma vez OBRIGADO.
Que bom que foi útil Samuel!
[]’s
Muito bom o seu tutorial sobre reports para Java EE. Parabéns!
Boa tarde David
Primeiro parabéns pelo seu trabalho, dedicação em apresentar de forma clara, exprecisa e fácil entendimento.
Minha duvida e gostaria de sua ajuda.
É possivel usar mais de um xml como datasourse para montar relatorios.
Desde já agradeço sua atenção.
Saulo, faz muito tempo que não uso e Jasper e que não respondo os comentários do blog. Vc deve ter resolvido já, mas o que eu faria é tentar mesclar esses dados antes de enviar para o relatório, ai eu enviaria um XML só. Abraço.
Parabéns pelo post, se é que pode se chamar esta AULA de post.
Muito bem explicado, arquivos à disposição e está sendo útil para mim em 2018.
Rss.
Que bom Leandro! Pretendo atualizar esse tutorial e colocá-lo em um livro de desenvolvimento web que distribuirei gratuitamente. Isso é um projeto para o segundo semestre, vamos ver se vai vingar 😀