SlideShare uma empresa Scribd logo
1 de 42
Baixar para ler offline
Tutorial: Técnicas de Geração de Relatórios com JasperReports

       Uma abordagem utilizando a ferramenta de design iReport




                PABLO BRUNO DE MOURA NÓBREGA




                    Fortaleza – CE, fevereiro de 2009




                    http://pablonobrega.wordpress.com
1.   INTRODUÇÃO ...........................................................................................................................3
2.   CONFIGURANDO O IREPORT ................................................................................................4
3.   A APLICAÇÃO...........................................................................................................................7
  3.1      O Banco de Dados................................................................................................................8
4. PREPARANDO OS RELATÓRIOS ...........................................................................................9
  4.1      Método passando conexão com o banco de dados...............................................................9
     4.1.1     Código Java da Solução .............................................................................................18
  4.2      Método passando ResultSet ...............................................................................................18
     4.2.1     Código Java da Solução .............................................................................................20
  4.3      Método passando Lista de Objetos ....................................................................................20
     4.3.1     Código Java da Solução .............................................................................................36
5. TESTES DE DOCUMENTOS COM SUBRELATÓRIOS.......................................................37
6. CONFIGURAÇÕES ÚTEIS......................................................................................................40
  6.1      Configurações de textFields...............................................................................................40
     6.1.1     Campo deve ficar em branco quando for nulo ...........................................................40
     6.1.2     Valor do campo não aparece quando ultrapassa o limite de espaço ..........................41
     6.1.3     Campo deve crescer de acordo com o valor a ser exibido .........................................41
     6.1.4     Campo deve ser exibido com formatação HTML......................................................42
1. INTRODUÇÃO

       Por diversas vezes tenho me deparado com pessoas tendo dificuldades para gerar relatórios
no JasperReports ou em utilizar os recursos do iReport - a ferramenta de design para o
JasperReports – e isso me incentivou a criar esse tutorial que mostra três técnicas para geração
desses documentos tão importantes em qualquer sistema: passando uma conexão com o banco,
passando um ResultSet (encapsulado na classe JRResultSetDataSource) e passando uma lista de
objetos de qualquer tipo (encapsulada na classe JRBeanCollectionDataSource).
       Duas outras características importantes desse tutorial são: o emprego de subrelatórios - uma
saída bastante útil em vários casos, sobretudo em relatórios complexos, e a passagem de parâmetros
para o relatório através de um Map.
       Para finalizar, disponibilizo o projeto do Eclipse no meu blog do WordPress
(http://pablonobrega.wordpress.com) a todos aqueles que desejam entender a estrutura da aplicação
finalizada. Na aplicação você encontrará os arquivos jrxml, os jasper, o script de criação do
banco, etc.




Requisitos do Tutorial:
   •   IReport 3.0 (http://jasperforge.org/plugins/project/project_home.php?group_id=83);
   •   JasperReports 3.0 (incluído o JAR no diretório do IReport);
   •   Eclipse Europa 3.3, ou algum outro IDE que aceite JSF (http://www.eclipse.org/europa/);
   •   Apache Tomcat 6.0, ou algum outro Servidor de Aplicação (http://tomcat.apache.org/);
   •   MySQL 5.0, ou algum outro SGBD (http://dev.mysql.com/downloads/);
2. CONFIGURANDO O IREPORT

       Como toda boa ferramenta, o iReport precisa que sejam feitas algumas configurações após a
instalação na máquina. Abaixo dou o exemplo de algumas que sempre uso para evitar a geração de
arquivos que não me interessam e outras para que eu possa visualizar o resultado da geração de
relatórios em PDF e em outros formatos (quando necessito).




Clique no item Opções do menu Opções.
Na aba Programas Externos, configure os programas que o iReport utilizará para abrir os arquivos gerados em outros
formatos (para efeito de testes internos). No exemplo acima, está configurado o Adobe Acrobat Reader para abrir
arquivos PDF.




 Na aba Cópia, marque a opção Sem backup para evitar que o iReport gere arquivos bak sempre que você efetua
alterações no relatório.
Na aba Compilador, marque a opção Usar o diretório do relatório para os compilados. Isso fará com que o iReport
gere o arquivo jasper no mesmo local onde está o jrxml. Além disso, desmarque a opção manter arquivo .java (se
disponível).
3. A APLICAÇÃO

        O objetivo da aplicação é muito simples: gerar relatório dos alunos cadastrados no banco e
seus respectivos professores.
        Alguns métodos são utilizados pelos três modelos de geração dos relatórios. São eles:
 private String getDiretorioReal(String diretorio) {
       HttpSession session = (HttpSession)
 FacesContext.getCurrentInstance().getExternalContext().getSession(false);
       return session.getServletContext().getRealPath(diretorio);
 }

Método que retorna o caminho completo de um arquivo ou pasta da aplicação.


 private String getContextPath() {
       HttpSession session = (HttpSession)
 FacesContext.getCurrentInstance().getExternalContext().getSession(false);
       return session.getServletContext().getContextPath();
 }

Método para retornar o nome da aplicação.


 private void preenchePdf(JasperPrint print) throws JRException {
        // Pego o caminho completo do PDF desde a raiz
        saida = getDiretorioReal("/pdf/relatorio.pdf");
        // Exporto para PDF
        JasperExportManager.exportReportToPdfFile(print, saida);
        /*
        * Jogo na variável saída o nome da aplicação mais o
        * caminho para o PDF. Essa variável será utilizada pela view
        */
        saida = getContextPath() + "/pdf/relatorio.pdf";
 }
Método que gera o arquivo PDF.


 public void criaConexao() throws ClassNotFoundException, SQLException {
       String endereco = "localhost";
       String porta = "3306";
       String banco = "academico";
       String usuario = "root";
       String senha = "";
       try {
             Class.forName("com.mysql.jdbc.Driver");
             conexao = DriverManager.getConnection("jdbc:mysql://" + endereco
                         + ":" + porta + "/" + banco + "?user=" + usuario
                         + "&password=" + senha);

         } catch (ClassNotFoundException ex) {
               throw ex;
         } catch (SQLException ex) {
               throw ex;
         }
 }
Método que cria a conexão com o banco de dados (chamado no construtor da classe).

 public Connection getConexao() {
       return conexao;
 }
Método que retorna a conexão aberta.
A página JSF que exibirá os relatórios tem o seguinte código:
 <?xml version="1.0" encoding="iso-8859-1" ?>
 <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
       xmlns="http://www.w3.org/1999/xhtml"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core">
       <f:view>
             <h:outputText rendered="#{empty relatorioBean.saida}"
 value="Relatório não gerado. Consulte o Administrador do Sistema." />
             <f:subview id="relatorio" rendered="#{not empty
 relatorioBean.saida}">
                   <iframe id="iframe" src="#{relatorioBean.saida}" width="99%"
                         height="600px" style="min-height: 400px;">
                   </iframe>
             </f:subview>
       </f:view>
 </jsp:root>

Observe que se a variável saída estiver vazia, uma mensagem de erro será exibida. Do contrário, será exibido o iFrame.
Utilizei essa técnica para evitar que a tela fique em branco quando o relatório não foi gerado por algum motivo.



3.1 O Banco de Dados

        Utilizo o SGBD MySQL 5.0 para efetuar as demonstrações. O nome do banco é acadêmico
e o Diagrama Relacional ficou da seguinte forma:




        Dica: se sua fonte de dados ficará no MySQL, utilize o MySQL Workbench (sucessor do
DBDesigner) para criar seu Diagrama Relacional. Foi com ele que gerei o modelo acima e o script
de criação do banco e a vantagem é que o software é totalmente gratuito.                           Segue link para
download: http://dev.mysql.com/downloads/workbench/5.1.html
4. PREPARANDO OS RELATÓRIOS

        Para fins de praticidade, utilizarei o Assistente de Relatório do próprio iReport para gerar o
layout do relatório e algumas pequenas modificações visuais serão feitas para que as informações
fiquem melhor distribuídas. É claro que, à medida que eu faça essas alterações, chamarei a atenção
do leitor para o layout que existia antes, como ficou e porque efetuei as mudanças.



4.1 Método passando conexão com o banco de dados

        Nesse primeiro exemplo, vamos preparar um relatório que receberá uma conexão com o
    banco de dados aberta pela nossa aplicação Java para gerar um PDF.




Selecione a opção Assistente de relatório.
Como iremos passar uma conexão com o banco de dados para o relatório, vamos ter que configurar qual a query a ser
executada pelo banco, o banco de dados, o schema (no caso de alguns SGBD’s), etc. Clique em Novo, na opção
Conexões / Fonte de Dados para configurar.




Selecione a opção Conexão de Banco de Dados JDBC.
Vamos agora configurar os parâmetros da conexão, como o driver JDBC, a URL de conexão, usuário, senha e o banco a
serem utilizados. Obs.: para alguns SGBD’s (como o Postgres), será preciso colocar o jar do banco na pasta lib do
iReport. Clique em Salvar.




Clique agora em Design query para modelarmos graficamente a consulta a ser executada.
Do lado esquerdo selecionamos as tabelas a serem utilizadas. Depois, em cada tabela, selecionamos os campos a serem
exibidos ou necessários ao relatório. Por último - sendo esse o caso - podemos modificar o tipo de JOIN que será
realizado entre as tabelas clicando duas vezes nos quadradinhos vermelhos.




A consulta agora aparece no campo reservado a ela. Clique em Próximo para continuar.
Nessa tela, vamos selecionar os campos da consulta que irão aparecer no relatório. Nesse caso passe todos para o select
da direita.




Nossa query vai retornar, em cada linha do resultado da consulta, o nome e a matrícula do aluno, o nome do professor,
etc. É lógico que não interessa para o usuário ver dados de cada aluno repetidos diversas vezes em toda exibição de um
professor dele. Para que o aluno seja mostrado somente uma vez e logo em seguida todos os seus professores,
precisamos de um agrupamento pelo id do aluno. Faça a configuração conforme a figura acima e clique em Próximo.
Escolhe o layout do relatório. Na seleção acima (colunar) cada dado fica abaixo do outro com seu label do lado
esquerdo, como veremos logo mais.




Pronto. Processo concluído. Agora precisamos somente clicar em Encerrar e fazer alguns ajustes.
Esse é o resultado. A área com o retângulo vermelho mostra onde está o agrupamento (o iReport cria uma banda para
ele). Isso significa que, para cada aluno, será exibido o seu id e logo abaixo cada um dos seus professores, juntamente
com o nome e a matrícula do aluno (isso para cada professor, o que representa uma repetição desnecessária de dados).




Para corrigir esse problema e também não mostrar o id do aluno, aumentei a banda do agrupamento (área marcada com
fundo preto) e coloquei lá a matrícula e o nome do aluno, além de apagar o label e o textField com o id do aluno.
Vamos agora Compilar nosso relatório para gerar o arquivo jasper a ser utilizado pela nossa aplicação. Selecione a
opção mostrada acima. Obs.: para acompanhar o andamento, erros e outros detalhes, consulte as abas Processos e
Console de Saída (marcadas com o círculo vermelho).




Como eu não havia salvo o arquivo, o iReport pede para que você dê um nome para o arquivo e selecione seu local.
Para aplicações web é interessante usar nomes sem espaço.
Vamos agora executar o relatório para ver o resultado final. O iReport vai conectar no banco, extrair as informações e
gerar o resultado. O relatório será mostrado no JRViewer (conforma seleção acima – marcação em vermelho). Para
gerar em outros formatos, selecione outra opção de visualização.




O resultado da geração é esse acima. Agora precisamos colocar o arquivo jasper gerado na nossa aplicação e prepará-la
para usar esse arquivo.
4.1.1 Código Java da Solução

 public String geraRelatorioPassandoConexao() {
       saida = null;
       String jasper = getDiretorioReal("/jasper/professores_por_aluno.jasper");
       Connection conexao = null;

        try {
                // Abro a conexão com o banco que será passada para o JasperReports
                conexao = new Conexao().getConexao();
                // Mando o jasper gerar o relatório
                JasperPrint print = JasperFillManager.fillReport(jasper, null,
 conexao);
              // Gero o PDF
              preenchePdf(print); // VEJA O MÉTODO NO CAPÍTULO 3 DO TUTORIAL
        } catch (Exception e) {
              e.printStackTrace();
        } finally {
              try {
                    // Sempre mando fechar a conexão, mesmo que tenha dado erro
                    if (conexao != null)
                          conexao.close();
              } catch (SQLException e) {

                }
                }

        return "exibeRelatorio";
 }


       Ao processarmos o método geraRelatorioPassandoConexao() do nosso Managed Bean, será
gerado o relatório em PDF e então a navigation rule “exibeRelatorio” será chamada.



4.2 Método passando ResultSet

       Para efeitos de praticidade, vamos utilizar o mesmo relatório anterior, pois não precisamos
fazer nenhuma mudança na configuração de um documento quando passamos a utilizar o ResultSet.
       Nesse tipo de abordagem, efetuamos a query no banco a partir da nossa própria aplicação e
enviamos para o JasperReports o ResultSet gerado encapsulado na classe JRResultSetDataSource.
O único detalhe com o qual devemos nos preocupar é o fato de os nomes das colunas do ResultSet
precisarem ser idênticos aos textFields do relatório. Para exemplificar, no nosso caso, para o id do
aluno, por exemplo, devemos usar o nome da coluna aluno_id_aluno e para o nome do professor o
nome da coluna deve ser professor_nome (veja figura abaixo), pois os nomes dos textFields no
iReport devem ser iguais aos alias gerados pela consulta ao banco.
Trecho da query configurada no iReport (marcado na cor vermelha).
4.2.1 Código Java da Solução

 public String geraRelatorioPassandoResultSet() {
       saida = null;
       String jasper = getDiretorioReal("/jasper/professores_por_aluno.jasper");
       Connection conexao = null;

         try {
             // Abro a conexão com o banco
             conexao = new Conexao().getConexao();
             // Gero o ResultSet que será enviado a partir da conexão aberta
             JRResultSetDataSource jrsds = new
 JRResultSetDataSource(getResultSet(conexao));
             // Mando o jasper gerar o relatório
             JasperPrint print = JasperFillManager.fillReport(jasper, null,
 jrsds);
             // Gero o PDF
             preenchePdf(print);
       } catch (Exception e) {
             e.printStackTrace();
       } finally {
             try {
                   // Sempre mando fechar a conexão, mesmo que tenha dado erro
                   if (conexao != null)
                         conexao.close();
             } catch (SQLException e) {
             }
       }
       return "exibeRelatorio";
 }
Observe que o ResultSet deve estar encapsulado pela classe JRResultSetDataSource.

 private ResultSet getResultSet(Connection conexao) throws SQLException,
       ClassNotFoundException {

       Statement stmt = conexao.createStatement();
       ResultSet rs = stmt.executeQuery("SELECT aluno.nome AS aluno_nome, " +
 "aluno.matricula AS aluno_matricula, professor.nome AS professor_nome, " +
 "aluno.id_aluno AS aluno_id_aluno FROM aluno aluno " +
 "INNER JOIN professores_alunos professores_alunos ON aluno.id_aluno = " +
 "professores_alunos.id_aluno INNER JOIN `professor` professor ON " +
 "professores_alunos.id_professor = professor.id_professor");

         return rs;
 }

Método que retorna o ResultSet da query executada no banco.



4.3 Método passando Lista de Objetos

        Esse é o método mais interessante de geração de relatórios. Ele pode ser utilizado como uma
alternativa aos dois outros métodos ou quando o relatório é muito complexo.
        Para facilitar, novamente aproveitei o modelo anterior existente, fazendo apenas algumas
pequenas alterações. Não se esqueça de salvar o novo relatório com outro nome. Coloquei ainda um
subrelatório que é bastante útil em situações complexas ou específicas. O legal dessa solução é que
o relatório principal vai receber uma lista de objetos e o subrelatório uma conexão com o banco.
Esse relatório não terá agrupamento de dados - vamos utilizar um subrelatório para os professores -, portanto, antes de
excluirmos o agrupamento, vamos mover todos os campos para a banda detail (marcada na cor vermelha). Isso é
necessário para que esses campos não sejam perdidos.




Vamos agora tirar o agrupamento do relatório. Entre na opção Agrupamentos do Relatório do menu Visualizar.
Selecione aluno_id_aluno e clique em Excluir.




Pronto. O relatório deve ficar com a aparência acima, já sem a banda de agrupamento por id do aluno.
Como não teremos dados sobre os professores dos alunos nesse relatório – isso será tarefa do subrelatório -, precisamos
mudar a query do banco. Entre em Query do Relatório no menu Data. Essa query será modificada e configurada apenas
para efeito de testes, já que iremos passar uma lista de objetos para o relatório e a query não será executada.




Apague toda a query para podermos refazer tudo novamente (o Query Designer tem um bug se quisermos tirar algumas
tabelas ou colunas da query anterior). Clique em Query Designer.
Selecione apenas a tabela aluno, marque todos os campos e clique em OK. Podem observar que a idéia é que esse
relatório seja mais detalhado.




A query do relatório ficará como a mostrada acima.
Precisamos que os textFields do nosso relatório batam com os nomes dos atributos da classe que estará na lista do
relatório. Na classe Aluno da minha aplicação, tenho os seguintes atributos: nome, matricula, situacaoFrequencia e
situacaoPagamento. Precisamos renomear os alias das colunas (marcados na cor vermelha) para os nomes acima.




Precisamos agora atualizar os textFields colocando o valor correto para o que contém aluno_matrícula (será agora
$F{matricula}) e para o que contém aluno_nome (será agora $F{nome}). Vamos também inserir os labels freqüência e
pagamento e inserir os textFields correpondentes com os valores $F{situacaoFrequencia} e $F{situacaoPagamento}}.
Para facilitar basta arrastar da estrutura, onde tem o nós Campos (lado esquerdo, inferior da tela) para o relatório.
Precisamos excluir também os campos relacionados ao professor. Ao final de tudo o relatório ficará como está a
imagem acima. Vamos agora adicionar o subrelatório. Clique no ícone marcado em vermelho na imagem acima para
fazer essa operação.




Crie uma área logo abaixo dos campos com o fundo preto (matrícula, freqüência, etc), de preferência utilizando a
largura do relatório por inteiro. A tela acima é mostrada. Deixe a conexão como está e entre com a query a ser
executada pelo subrelatório. No exemplo acima coloquei a id do aluno com o valor 1 apenas para o iReport deixar eu
passar dessa tela. Clique em Próximo.
Marque os campos que deseja que o iReport exiba. No nosso caso, vamos selecionar todos. Clique em Finalizar.




Selecione o layout do relatório. Decidi que o relatório funcionará com um cabeçalho superior e os valores abaixo (uma
linha para cada professor do aluno), então selecionei o layout tabular.
Esse passo é muito importante. Nele vamos indicar o nome do subrelatório e como será referenciado pelo relatório
principal. Como nosso relatório e o subrelatório podem mudar seus caminhos vamos dizer para o iReport que o caminho
para o subrelatório será passado através de um parâmetro chamado SUBREPORT_DIR.




O subrelatório deve ter uma aparência semelhante a que se encontra na imagem acima. Fiz apenas alguma modificações
nas larguras dos textFields.
Observem como está a query do relatório. Logo mais, o número 1 será modificado por um parâmetro.




Voltando ao relatório principal, vamos agora modificar algumas configurações do subrelatório. Clique duas vezes em
cima dele.
Na aba Sub-Relatório (Outro) podemos observar que o iReport se encarregou de configurar o caminho para o
subrelatório concatenando o seu nome com o diretório passado por parâmetro ($P{SUBREPORT_DIR}). Vamos agora
passar um parâmetro do relatório principal para o subrelatório que servirá para fazer a query listando os professores de
um determinado aluno. Clique no botão Adicionar.




Na janela a seguir, digite idAluno no Nome de Parâmetro do Sub-Relatório. Depois clique no botão do lado direito
(marcado na cor vermelha).
Na expressão, digite $F{idAluno}. Clique em Aplicar.




Com essa configuração, estamos dizendo para o JasperReports que para cada aluno colocado na tela, ele vai gerar um
subrelatório que receberá como parâmetro o id do aluno que foi processado. Clique em OK.
A tela deve ficar como a que está acima.




Na aba Subrelatório, mude a Expressão de Conexão/Fonte de Dados de $P{subConnection} para
$P{REPORT_CONNECTION}. Com isso você está dizendo para o JasperReports que a conexão com o banco de dados
utilizada pelo subrelatório, está na chave REPORT_CONNECTION da lista de parâmetros.
Voltando para o subrelatório, vamos agora mudar a Query do Relatório para poder receber o parâmetro passado e
mostrar somente os professores do aluno correto. Entre novamente na opção Query do Relatório do menu Data.




Mude o valor ‘1’ que tinha antes para $P{idAluno}, o parâmetro que está vindo do relatório principal. Clique em OK.
Vamos agora preparar o subrelatório para receber o parâmetro do relatório principal. Entre na opção Parâmetros do
Relatório, no menu Visualizar.




Na aba Parâmetros, clique no botão Novo.
Coloque o nome do parâmetro idAluno e informe que é do tipo Integer. Clique em OK. Salve os dois relatórios e mande
compilar.
4.3.1 Código Java da Solução
 private ArrayList<Aluno> getListaAlunos(Connection conexao)
             throws SQLException {
       return (ArrayList<Aluno>) new AlunoDao().loadAll(conexao);
 }




 public String geraRelatorioPassandoListaDeObjetos() {
       saida = null;
       String jasper =
 getDiretorioReal("/jasper/professores_por_aluno_com_lista.jasper");
       Connection conexao = null;

         try {
                 // Conexão com o banco para o segundo relatório
                 conexao = new Conexao().getConexao();
                 // criação dos parametros
                 Map<String, Object> map = new HashMap<String, Object>();
                 // conexão com o banco que será utilizada pelo subrelatório
                 map.put("REPORT_CONNECTION", conexao);
                 // pego o caminho do diretório onde se encontra o subrelatório
                 map.put("SUBREPORT_DIR", getDiretorioReal("/jasper/") + "/");
                 ArrayList<Aluno> alunos = getListaAlunos(conexao);

             JRBeanCollectionDataSource ds = new
 JRBeanCollectionDataSource(alunos);
             /*
              * Mando o jasper gerar o relatório. Nesse caso passo o map,
              * já que ele tem dois parâmetros que serão utilizados
              */
             JasperPrint print = JasperFillManager.fillReport(jasper, map, ds);
             // Gero o PDF
             preenchePdf(print);
       } catch (Exception e) {
             e.printStackTrace();
       }

         return "exibeRelatorio";
 }

Observe que no caso de passarmos uma lista, devemos encapsulá-la na classe JRBeanCollectionDataSource.
5. TESTES DE DOCUMENTOS COM SUBRELATÓRIOS

        Um grande problema com o qual me deparei quando comecei a usar o iReport foi o de
realizar testes quando o relatório principal possuía uma subrelatório. Isso porque o subrelatório é
referenciado pelo JasperReports através do parâmetro SUBREPORT_DIR e quando mandamos
executar o relatório principal - caso você não efetue a configuração a seguir - o subrelatório não é
encontrado. Para contornar isso, realizaremos uma configuração adicional, conforme as telas a
seguir (o exemplo abaixo se aplica no exemplo de relatório com listas explicado no subcapítulo
4.3):




Entre nos parâmetros do relatório principal, escolha SUBREPORT_DIR e clique em Modificar.
Em Valor Padrão da Expressão, coloque o caminho para o diretório onde se encontra o arquivo jrxml do subrelatório.




Agora clique em Executar relatório (usar conexão ativa).
A tela a seguir será exibida. Clique em Usar padrão.




Pronto! O relatório principal foi gerado executando a consulta no banco e o subrelatório funcionou com a mesma
conexão utilizada pelo relatório principal. Observe que cada aluno tem sua lista de professores.
6. CONFIGURAÇÕES ÚTEIS
6.1 Configurações de textFields

        As configurações a seguir se aplicam quando se faz a operação a seguir:




Clique com o botão direito sobre o textField e escolha a opção Propriedades


6.1.1 Campo deve ficar em branco quando for nulo




Marque a opção Em branco quando for nulo da aba Campo texto.
6.1.2 Valor do campo não aparece quando ultrapassa o limite de espaço




Marque a opção Imprimir quando detalhes excederem na aba Comum.

6.1.3 Campo deve crescer de acordo com o valor a ser exibido




Marque a opção Aumentar quando exceder na aba Campo texto.
6.1.4 Campo deve ser exibido com formatação HTML




Marque a opção HTML no item Markup da aba Fonte.

Mais conteúdo relacionado

Mais procurados

Curso de Java (Parte 6) Introdução a Front-end
Curso de Java (Parte 6) Introdução a Front-endCurso de Java (Parte 6) Introdução a Front-end
Curso de Java (Parte 6) Introdução a Front-endMario Sergio
 
Programação para Web II: JavaServer Pages
Programação para Web II:  JavaServer PagesProgramação para Web II:  JavaServer Pages
Programação para Web II: JavaServer PagesAlex Camargo
 
Dsi 015 - poo e php - conexão com bancos de dados usando pdo
Dsi   015 - poo e php - conexão com bancos de dados usando pdoDsi   015 - poo e php - conexão com bancos de dados usando pdo
Dsi 015 - poo e php - conexão com bancos de dados usando pdoJorge Luís Gregório
 
Curso Java (Parte 8) Web Service REST
Curso Java (Parte 8) Web Service RESTCurso Java (Parte 8) Web Service REST
Curso Java (Parte 8) Web Service RESTMario Sergio
 
hibernate annotation
hibernate annotationhibernate annotation
hibernate annotationeduardo dias
 
Django Módulo Básico Parte I - Desenvolvimento de uma aplicação Web
Django Módulo Básico Parte I - Desenvolvimento de uma aplicação WebDjango Módulo Básico Parte I - Desenvolvimento de uma aplicação Web
Django Módulo Básico Parte I - Desenvolvimento de uma aplicação Webantonio sérgio nogueira
 
Manual de Usuário - TCC André Luiz Jamarino Abekawa
Manual de Usuário - TCC André Luiz Jamarino AbekawaManual de Usuário - TCC André Luiz Jamarino Abekawa
Manual de Usuário - TCC André Luiz Jamarino AbekawaAndré Luiz Jamarino Abekawa
 
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...Tchelinux
 
Introdução ao Ruby On Rails
Introdução ao Ruby On RailsIntrodução ao Ruby On Rails
Introdução ao Ruby On RailsMilton Moura
 
Tutorial para criação de módulo no Xoops 2.4
Tutorial para criação de módulo no Xoops 2.4Tutorial para criação de módulo no Xoops 2.4
Tutorial para criação de módulo no Xoops 2.4Fabio Telles Rodriguez
 
Desenvolvimento de sistemas web com PHP Frameworks - Aula 3
Desenvolvimento de sistemas web com PHP Frameworks - Aula 3Desenvolvimento de sistemas web com PHP Frameworks - Aula 3
Desenvolvimento de sistemas web com PHP Frameworks - Aula 3Thyago Maia
 
Python e Django
Python e DjangoPython e Django
Python e Djangopugpe
 
Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3Thyago Maia
 

Mais procurados (18)

Curso de Java (Parte 6) Introdução a Front-end
Curso de Java (Parte 6) Introdução a Front-endCurso de Java (Parte 6) Introdução a Front-end
Curso de Java (Parte 6) Introdução a Front-end
 
Programação para Web II: JavaServer Pages
Programação para Web II:  JavaServer PagesProgramação para Web II:  JavaServer Pages
Programação para Web II: JavaServer Pages
 
Dsi 015 - poo e php - conexão com bancos de dados usando pdo
Dsi   015 - poo e php - conexão com bancos de dados usando pdoDsi   015 - poo e php - conexão com bancos de dados usando pdo
Dsi 015 - poo e php - conexão com bancos de dados usando pdo
 
CakePHP
CakePHPCakePHP
CakePHP
 
Curso Java (Parte 8) Web Service REST
Curso Java (Parte 8) Web Service RESTCurso Java (Parte 8) Web Service REST
Curso Java (Parte 8) Web Service REST
 
hibernate annotation
hibernate annotationhibernate annotation
hibernate annotation
 
Django Módulo Básico Parte I - Desenvolvimento de uma aplicação Web
Django Módulo Básico Parte I - Desenvolvimento de uma aplicação WebDjango Módulo Básico Parte I - Desenvolvimento de uma aplicação Web
Django Módulo Básico Parte I - Desenvolvimento de uma aplicação Web
 
Manual de Usuário - TCC André Luiz Jamarino Abekawa
Manual de Usuário - TCC André Luiz Jamarino AbekawaManual de Usuário - TCC André Luiz Jamarino Abekawa
Manual de Usuário - TCC André Luiz Jamarino Abekawa
 
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
 
Introdução ao Ruby On Rails
Introdução ao Ruby On RailsIntrodução ao Ruby On Rails
Introdução ao Ruby On Rails
 
Ruby On Rails Regis
Ruby On Rails RegisRuby On Rails Regis
Ruby On Rails Regis
 
Tutorial para criação de módulo no Xoops 2.4
Tutorial para criação de módulo no Xoops 2.4Tutorial para criação de módulo no Xoops 2.4
Tutorial para criação de módulo no Xoops 2.4
 
Desenvolvimento de sistemas web com PHP Frameworks - Aula 3
Desenvolvimento de sistemas web com PHP Frameworks - Aula 3Desenvolvimento de sistemas web com PHP Frameworks - Aula 3
Desenvolvimento de sistemas web com PHP Frameworks - Aula 3
 
Python e Django
Python e DjangoPython e Django
Python e Django
 
Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3
 
Java 08
Java 08Java 08
Java 08
 
Minicurso Yii2
Minicurso Yii2Minicurso Yii2
Minicurso Yii2
 
Drupal 7
Drupal 7Drupal 7
Drupal 7
 

Destaque

Apresentação - QlikView
Apresentação - QlikViewApresentação - QlikView
Apresentação - QlikViewJDSBD
 
Construindo aplicações com netbeans
Construindo aplicações com netbeansConstruindo aplicações com netbeans
Construindo aplicações com netbeansSliedesharessbarbosa
 
Aula vetores e matrizes (arrays)
Aula vetores e matrizes (arrays)Aula vetores e matrizes (arrays)
Aula vetores e matrizes (arrays)profjr
 
Aula qlikview tipo de licenças
Aula qlikview tipo de licençasAula qlikview tipo de licenças
Aula qlikview tipo de licençasRoberto Oliveira
 
Introdução a Lógica e a Algoritmos
Introdução a Lógica e a AlgoritmosIntrodução a Lógica e a Algoritmos
Introdução a Lógica e a AlgoritmosMicael Coutinho
 

Destaque (9)

Apresentação - QlikView
Apresentação - QlikViewApresentação - QlikView
Apresentação - QlikView
 
Construindo aplicações com netbeans
Construindo aplicações com netbeansConstruindo aplicações com netbeans
Construindo aplicações com netbeans
 
Aula vetores e matrizes (arrays)
Aula vetores e matrizes (arrays)Aula vetores e matrizes (arrays)
Aula vetores e matrizes (arrays)
 
Aula qlikview tipo de licenças
Aula qlikview tipo de licençasAula qlikview tipo de licenças
Aula qlikview tipo de licenças
 
Apresentação QlikView
Apresentação QlikViewApresentação QlikView
Apresentação QlikView
 
Business intelligence com QlikView
Business intelligence com QlikViewBusiness intelligence com QlikView
Business intelligence com QlikView
 
Introdução a Lógica e a Algoritmos
Introdução a Lógica e a AlgoritmosIntrodução a Lógica e a Algoritmos
Introdução a Lógica e a Algoritmos
 
Algoritmos
AlgoritmosAlgoritmos
Algoritmos
 
Qmeeting - Projetos de bi
Qmeeting  - Projetos de biQmeeting  - Projetos de bi
Qmeeting - Projetos de bi
 

Semelhante a JasperReports Tecnicas de geracao_de_relatorios1

Usando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para phpUsando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para phpbrunocf007
 
Gerência de redes utilizando o cacti
Gerência de redes utilizando o cactiGerência de redes utilizando o cacti
Gerência de redes utilizando o cactiIsraelCunha
 
Documentação CakePHP - Português Br
Documentação CakePHP -  Português BrDocumentação CakePHP -  Português Br
Documentação CakePHP - Português BrLuiz Ladeira
 
Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01julianabdpaiva
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoCezinha Anjos
 
Produtividade com JavaServer Faces
Produtividade com JavaServer FacesProdutividade com JavaServer Faces
Produtividade com JavaServer FacesEduardo Bregaida
 
Spring & Struts
Spring & StrutsSpring & Struts
Spring & Strutseduan
 
3260 php truquesmagicos %281%29
3260 php truquesmagicos %281%293260 php truquesmagicos %281%29
3260 php truquesmagicos %281%29Juliana Nascimento
 
Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Frameworkelliando dias
 
Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010Fabrízio Mello
 
TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoTDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoCezinha Anjos
 
Oficina PostgreSQL Básico Latinoware 2012
Oficina PostgreSQL Básico Latinoware 2012Oficina PostgreSQL Básico Latinoware 2012
Oficina PostgreSQL Básico Latinoware 2012Fabrízio Mello
 
LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04Carlos Santos
 
Conectando seu banco de dados usando jdbc
Conectando seu banco de dados usando jdbcConectando seu banco de dados usando jdbc
Conectando seu banco de dados usando jdbcJeison Barros
 

Semelhante a JasperReports Tecnicas de geracao_de_relatorios1 (20)

Usando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para phpUsando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para php
 
Gerência de redes utilizando o cacti
Gerência de redes utilizando o cactiGerência de redes utilizando o cacti
Gerência de redes utilizando o cacti
 
Documentação CakePHP - Português Br
Documentação CakePHP -  Português BrDocumentação CakePHP -  Português Br
Documentação CakePHP - Português Br
 
Acessando o MySql com o Python
Acessando o MySql com o PythonAcessando o MySql com o Python
Acessando o MySql com o Python
 
Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direito
 
Produtividade com JavaServer Faces
Produtividade com JavaServer FacesProdutividade com JavaServer Faces
Produtividade com JavaServer Faces
 
Spring & Struts
Spring & StrutsSpring & Struts
Spring & Struts
 
3260 php truquesmagicos %281%29
3260 php truquesmagicos %281%293260 php truquesmagicos %281%29
3260 php truquesmagicos %281%29
 
3260 php truquesmagicos
3260 php truquesmagicos3260 php truquesmagicos
3260 php truquesmagicos
 
Tw Course Ajax 2007 Ap05
Tw Course Ajax 2007 Ap05Tw Course Ajax 2007 Ap05
Tw Course Ajax 2007 Ap05
 
Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Framework
 
Django Módulo Básico Parte II
Django Módulo Básico Parte IIDjango Módulo Básico Parte II
Django Módulo Básico Parte II
 
Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010
 
TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoTDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direito
 
Oficina PostgreSQL Básico Latinoware 2012
Oficina PostgreSQL Básico Latinoware 2012Oficina PostgreSQL Básico Latinoware 2012
Oficina PostgreSQL Básico Latinoware 2012
 
Python 08
Python 08Python 08
Python 08
 
Java Seminar
Java SeminarJava Seminar
Java Seminar
 
LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04
 
Conectando seu banco de dados usando jdbc
Conectando seu banco de dados usando jdbcConectando seu banco de dados usando jdbc
Conectando seu banco de dados usando jdbc
 

JasperReports Tecnicas de geracao_de_relatorios1

  • 1. Tutorial: Técnicas de Geração de Relatórios com JasperReports Uma abordagem utilizando a ferramenta de design iReport PABLO BRUNO DE MOURA NÓBREGA Fortaleza – CE, fevereiro de 2009 http://pablonobrega.wordpress.com
  • 2. 1. INTRODUÇÃO ...........................................................................................................................3 2. CONFIGURANDO O IREPORT ................................................................................................4 3. A APLICAÇÃO...........................................................................................................................7 3.1 O Banco de Dados................................................................................................................8 4. PREPARANDO OS RELATÓRIOS ...........................................................................................9 4.1 Método passando conexão com o banco de dados...............................................................9 4.1.1 Código Java da Solução .............................................................................................18 4.2 Método passando ResultSet ...............................................................................................18 4.2.1 Código Java da Solução .............................................................................................20 4.3 Método passando Lista de Objetos ....................................................................................20 4.3.1 Código Java da Solução .............................................................................................36 5. TESTES DE DOCUMENTOS COM SUBRELATÓRIOS.......................................................37 6. CONFIGURAÇÕES ÚTEIS......................................................................................................40 6.1 Configurações de textFields...............................................................................................40 6.1.1 Campo deve ficar em branco quando for nulo ...........................................................40 6.1.2 Valor do campo não aparece quando ultrapassa o limite de espaço ..........................41 6.1.3 Campo deve crescer de acordo com o valor a ser exibido .........................................41 6.1.4 Campo deve ser exibido com formatação HTML......................................................42
  • 3. 1. INTRODUÇÃO Por diversas vezes tenho me deparado com pessoas tendo dificuldades para gerar relatórios no JasperReports ou em utilizar os recursos do iReport - a ferramenta de design para o JasperReports – e isso me incentivou a criar esse tutorial que mostra três técnicas para geração desses documentos tão importantes em qualquer sistema: passando uma conexão com o banco, passando um ResultSet (encapsulado na classe JRResultSetDataSource) e passando uma lista de objetos de qualquer tipo (encapsulada na classe JRBeanCollectionDataSource). Duas outras características importantes desse tutorial são: o emprego de subrelatórios - uma saída bastante útil em vários casos, sobretudo em relatórios complexos, e a passagem de parâmetros para o relatório através de um Map. Para finalizar, disponibilizo o projeto do Eclipse no meu blog do WordPress (http://pablonobrega.wordpress.com) a todos aqueles que desejam entender a estrutura da aplicação finalizada. Na aplicação você encontrará os arquivos jrxml, os jasper, o script de criação do banco, etc. Requisitos do Tutorial: • IReport 3.0 (http://jasperforge.org/plugins/project/project_home.php?group_id=83); • JasperReports 3.0 (incluído o JAR no diretório do IReport); • Eclipse Europa 3.3, ou algum outro IDE que aceite JSF (http://www.eclipse.org/europa/); • Apache Tomcat 6.0, ou algum outro Servidor de Aplicação (http://tomcat.apache.org/); • MySQL 5.0, ou algum outro SGBD (http://dev.mysql.com/downloads/);
  • 4. 2. CONFIGURANDO O IREPORT Como toda boa ferramenta, o iReport precisa que sejam feitas algumas configurações após a instalação na máquina. Abaixo dou o exemplo de algumas que sempre uso para evitar a geração de arquivos que não me interessam e outras para que eu possa visualizar o resultado da geração de relatórios em PDF e em outros formatos (quando necessito). Clique no item Opções do menu Opções.
  • 5. Na aba Programas Externos, configure os programas que o iReport utilizará para abrir os arquivos gerados em outros formatos (para efeito de testes internos). No exemplo acima, está configurado o Adobe Acrobat Reader para abrir arquivos PDF. Na aba Cópia, marque a opção Sem backup para evitar que o iReport gere arquivos bak sempre que você efetua alterações no relatório.
  • 6. Na aba Compilador, marque a opção Usar o diretório do relatório para os compilados. Isso fará com que o iReport gere o arquivo jasper no mesmo local onde está o jrxml. Além disso, desmarque a opção manter arquivo .java (se disponível).
  • 7. 3. A APLICAÇÃO O objetivo da aplicação é muito simples: gerar relatório dos alunos cadastrados no banco e seus respectivos professores. Alguns métodos são utilizados pelos três modelos de geração dos relatórios. São eles: private String getDiretorioReal(String diretorio) { HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false); return session.getServletContext().getRealPath(diretorio); } Método que retorna o caminho completo de um arquivo ou pasta da aplicação. private String getContextPath() { HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false); return session.getServletContext().getContextPath(); } Método para retornar o nome da aplicação. private void preenchePdf(JasperPrint print) throws JRException { // Pego o caminho completo do PDF desde a raiz saida = getDiretorioReal("/pdf/relatorio.pdf"); // Exporto para PDF JasperExportManager.exportReportToPdfFile(print, saida); /* * Jogo na variável saída o nome da aplicação mais o * caminho para o PDF. Essa variável será utilizada pela view */ saida = getContextPath() + "/pdf/relatorio.pdf"; } Método que gera o arquivo PDF. public void criaConexao() throws ClassNotFoundException, SQLException { String endereco = "localhost"; String porta = "3306"; String banco = "academico"; String usuario = "root"; String senha = ""; try { Class.forName("com.mysql.jdbc.Driver"); conexao = DriverManager.getConnection("jdbc:mysql://" + endereco + ":" + porta + "/" + banco + "?user=" + usuario + "&password=" + senha); } catch (ClassNotFoundException ex) { throw ex; } catch (SQLException ex) { throw ex; } } Método que cria a conexão com o banco de dados (chamado no construtor da classe). public Connection getConexao() { return conexao; } Método que retorna a conexão aberta.
  • 8. A página JSF que exibirá os relatórios tem o seguinte código: <?xml version="1.0" encoding="iso-8859-1" ?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <f:view> <h:outputText rendered="#{empty relatorioBean.saida}" value="Relatório não gerado. Consulte o Administrador do Sistema." /> <f:subview id="relatorio" rendered="#{not empty relatorioBean.saida}"> <iframe id="iframe" src="#{relatorioBean.saida}" width="99%" height="600px" style="min-height: 400px;"> </iframe> </f:subview> </f:view> </jsp:root> Observe que se a variável saída estiver vazia, uma mensagem de erro será exibida. Do contrário, será exibido o iFrame. Utilizei essa técnica para evitar que a tela fique em branco quando o relatório não foi gerado por algum motivo. 3.1 O Banco de Dados Utilizo o SGBD MySQL 5.0 para efetuar as demonstrações. O nome do banco é acadêmico e o Diagrama Relacional ficou da seguinte forma: Dica: se sua fonte de dados ficará no MySQL, utilize o MySQL Workbench (sucessor do DBDesigner) para criar seu Diagrama Relacional. Foi com ele que gerei o modelo acima e o script de criação do banco e a vantagem é que o software é totalmente gratuito. Segue link para download: http://dev.mysql.com/downloads/workbench/5.1.html
  • 9. 4. PREPARANDO OS RELATÓRIOS Para fins de praticidade, utilizarei o Assistente de Relatório do próprio iReport para gerar o layout do relatório e algumas pequenas modificações visuais serão feitas para que as informações fiquem melhor distribuídas. É claro que, à medida que eu faça essas alterações, chamarei a atenção do leitor para o layout que existia antes, como ficou e porque efetuei as mudanças. 4.1 Método passando conexão com o banco de dados Nesse primeiro exemplo, vamos preparar um relatório que receberá uma conexão com o banco de dados aberta pela nossa aplicação Java para gerar um PDF. Selecione a opção Assistente de relatório.
  • 10. Como iremos passar uma conexão com o banco de dados para o relatório, vamos ter que configurar qual a query a ser executada pelo banco, o banco de dados, o schema (no caso de alguns SGBD’s), etc. Clique em Novo, na opção Conexões / Fonte de Dados para configurar. Selecione a opção Conexão de Banco de Dados JDBC.
  • 11. Vamos agora configurar os parâmetros da conexão, como o driver JDBC, a URL de conexão, usuário, senha e o banco a serem utilizados. Obs.: para alguns SGBD’s (como o Postgres), será preciso colocar o jar do banco na pasta lib do iReport. Clique em Salvar. Clique agora em Design query para modelarmos graficamente a consulta a ser executada.
  • 12. Do lado esquerdo selecionamos as tabelas a serem utilizadas. Depois, em cada tabela, selecionamos os campos a serem exibidos ou necessários ao relatório. Por último - sendo esse o caso - podemos modificar o tipo de JOIN que será realizado entre as tabelas clicando duas vezes nos quadradinhos vermelhos. A consulta agora aparece no campo reservado a ela. Clique em Próximo para continuar.
  • 13. Nessa tela, vamos selecionar os campos da consulta que irão aparecer no relatório. Nesse caso passe todos para o select da direita. Nossa query vai retornar, em cada linha do resultado da consulta, o nome e a matrícula do aluno, o nome do professor, etc. É lógico que não interessa para o usuário ver dados de cada aluno repetidos diversas vezes em toda exibição de um professor dele. Para que o aluno seja mostrado somente uma vez e logo em seguida todos os seus professores, precisamos de um agrupamento pelo id do aluno. Faça a configuração conforme a figura acima e clique em Próximo.
  • 14. Escolhe o layout do relatório. Na seleção acima (colunar) cada dado fica abaixo do outro com seu label do lado esquerdo, como veremos logo mais. Pronto. Processo concluído. Agora precisamos somente clicar em Encerrar e fazer alguns ajustes.
  • 15. Esse é o resultado. A área com o retângulo vermelho mostra onde está o agrupamento (o iReport cria uma banda para ele). Isso significa que, para cada aluno, será exibido o seu id e logo abaixo cada um dos seus professores, juntamente com o nome e a matrícula do aluno (isso para cada professor, o que representa uma repetição desnecessária de dados). Para corrigir esse problema e também não mostrar o id do aluno, aumentei a banda do agrupamento (área marcada com fundo preto) e coloquei lá a matrícula e o nome do aluno, além de apagar o label e o textField com o id do aluno.
  • 16. Vamos agora Compilar nosso relatório para gerar o arquivo jasper a ser utilizado pela nossa aplicação. Selecione a opção mostrada acima. Obs.: para acompanhar o andamento, erros e outros detalhes, consulte as abas Processos e Console de Saída (marcadas com o círculo vermelho). Como eu não havia salvo o arquivo, o iReport pede para que você dê um nome para o arquivo e selecione seu local. Para aplicações web é interessante usar nomes sem espaço.
  • 17. Vamos agora executar o relatório para ver o resultado final. O iReport vai conectar no banco, extrair as informações e gerar o resultado. O relatório será mostrado no JRViewer (conforma seleção acima – marcação em vermelho). Para gerar em outros formatos, selecione outra opção de visualização. O resultado da geração é esse acima. Agora precisamos colocar o arquivo jasper gerado na nossa aplicação e prepará-la para usar esse arquivo.
  • 18. 4.1.1 Código Java da Solução public String geraRelatorioPassandoConexao() { saida = null; String jasper = getDiretorioReal("/jasper/professores_por_aluno.jasper"); Connection conexao = null; try { // Abro a conexão com o banco que será passada para o JasperReports conexao = new Conexao().getConexao(); // Mando o jasper gerar o relatório JasperPrint print = JasperFillManager.fillReport(jasper, null, conexao); // Gero o PDF preenchePdf(print); // VEJA O MÉTODO NO CAPÍTULO 3 DO TUTORIAL } catch (Exception e) { e.printStackTrace(); } finally { try { // Sempre mando fechar a conexão, mesmo que tenha dado erro if (conexao != null) conexao.close(); } catch (SQLException e) { } } return "exibeRelatorio"; } Ao processarmos o método geraRelatorioPassandoConexao() do nosso Managed Bean, será gerado o relatório em PDF e então a navigation rule “exibeRelatorio” será chamada. 4.2 Método passando ResultSet Para efeitos de praticidade, vamos utilizar o mesmo relatório anterior, pois não precisamos fazer nenhuma mudança na configuração de um documento quando passamos a utilizar o ResultSet. Nesse tipo de abordagem, efetuamos a query no banco a partir da nossa própria aplicação e enviamos para o JasperReports o ResultSet gerado encapsulado na classe JRResultSetDataSource. O único detalhe com o qual devemos nos preocupar é o fato de os nomes das colunas do ResultSet precisarem ser idênticos aos textFields do relatório. Para exemplificar, no nosso caso, para o id do aluno, por exemplo, devemos usar o nome da coluna aluno_id_aluno e para o nome do professor o nome da coluna deve ser professor_nome (veja figura abaixo), pois os nomes dos textFields no iReport devem ser iguais aos alias gerados pela consulta ao banco.
  • 19. Trecho da query configurada no iReport (marcado na cor vermelha).
  • 20. 4.2.1 Código Java da Solução public String geraRelatorioPassandoResultSet() { saida = null; String jasper = getDiretorioReal("/jasper/professores_por_aluno.jasper"); Connection conexao = null; try { // Abro a conexão com o banco conexao = new Conexao().getConexao(); // Gero o ResultSet que será enviado a partir da conexão aberta JRResultSetDataSource jrsds = new JRResultSetDataSource(getResultSet(conexao)); // Mando o jasper gerar o relatório JasperPrint print = JasperFillManager.fillReport(jasper, null, jrsds); // Gero o PDF preenchePdf(print); } catch (Exception e) { e.printStackTrace(); } finally { try { // Sempre mando fechar a conexão, mesmo que tenha dado erro if (conexao != null) conexao.close(); } catch (SQLException e) { } } return "exibeRelatorio"; } Observe que o ResultSet deve estar encapsulado pela classe JRResultSetDataSource. private ResultSet getResultSet(Connection conexao) throws SQLException, ClassNotFoundException { Statement stmt = conexao.createStatement(); ResultSet rs = stmt.executeQuery("SELECT aluno.nome AS aluno_nome, " + "aluno.matricula AS aluno_matricula, professor.nome AS professor_nome, " + "aluno.id_aluno AS aluno_id_aluno FROM aluno aluno " + "INNER JOIN professores_alunos professores_alunos ON aluno.id_aluno = " + "professores_alunos.id_aluno INNER JOIN `professor` professor ON " + "professores_alunos.id_professor = professor.id_professor"); return rs; } Método que retorna o ResultSet da query executada no banco. 4.3 Método passando Lista de Objetos Esse é o método mais interessante de geração de relatórios. Ele pode ser utilizado como uma alternativa aos dois outros métodos ou quando o relatório é muito complexo. Para facilitar, novamente aproveitei o modelo anterior existente, fazendo apenas algumas pequenas alterações. Não se esqueça de salvar o novo relatório com outro nome. Coloquei ainda um subrelatório que é bastante útil em situações complexas ou específicas. O legal dessa solução é que o relatório principal vai receber uma lista de objetos e o subrelatório uma conexão com o banco.
  • 21. Esse relatório não terá agrupamento de dados - vamos utilizar um subrelatório para os professores -, portanto, antes de excluirmos o agrupamento, vamos mover todos os campos para a banda detail (marcada na cor vermelha). Isso é necessário para que esses campos não sejam perdidos. Vamos agora tirar o agrupamento do relatório. Entre na opção Agrupamentos do Relatório do menu Visualizar.
  • 22. Selecione aluno_id_aluno e clique em Excluir. Pronto. O relatório deve ficar com a aparência acima, já sem a banda de agrupamento por id do aluno.
  • 23. Como não teremos dados sobre os professores dos alunos nesse relatório – isso será tarefa do subrelatório -, precisamos mudar a query do banco. Entre em Query do Relatório no menu Data. Essa query será modificada e configurada apenas para efeito de testes, já que iremos passar uma lista de objetos para o relatório e a query não será executada. Apague toda a query para podermos refazer tudo novamente (o Query Designer tem um bug se quisermos tirar algumas tabelas ou colunas da query anterior). Clique em Query Designer.
  • 24. Selecione apenas a tabela aluno, marque todos os campos e clique em OK. Podem observar que a idéia é que esse relatório seja mais detalhado. A query do relatório ficará como a mostrada acima.
  • 25. Precisamos que os textFields do nosso relatório batam com os nomes dos atributos da classe que estará na lista do relatório. Na classe Aluno da minha aplicação, tenho os seguintes atributos: nome, matricula, situacaoFrequencia e situacaoPagamento. Precisamos renomear os alias das colunas (marcados na cor vermelha) para os nomes acima. Precisamos agora atualizar os textFields colocando o valor correto para o que contém aluno_matrícula (será agora $F{matricula}) e para o que contém aluno_nome (será agora $F{nome}). Vamos também inserir os labels freqüência e pagamento e inserir os textFields correpondentes com os valores $F{situacaoFrequencia} e $F{situacaoPagamento}}. Para facilitar basta arrastar da estrutura, onde tem o nós Campos (lado esquerdo, inferior da tela) para o relatório.
  • 26. Precisamos excluir também os campos relacionados ao professor. Ao final de tudo o relatório ficará como está a imagem acima. Vamos agora adicionar o subrelatório. Clique no ícone marcado em vermelho na imagem acima para fazer essa operação. Crie uma área logo abaixo dos campos com o fundo preto (matrícula, freqüência, etc), de preferência utilizando a largura do relatório por inteiro. A tela acima é mostrada. Deixe a conexão como está e entre com a query a ser executada pelo subrelatório. No exemplo acima coloquei a id do aluno com o valor 1 apenas para o iReport deixar eu passar dessa tela. Clique em Próximo.
  • 27. Marque os campos que deseja que o iReport exiba. No nosso caso, vamos selecionar todos. Clique em Finalizar. Selecione o layout do relatório. Decidi que o relatório funcionará com um cabeçalho superior e os valores abaixo (uma linha para cada professor do aluno), então selecionei o layout tabular.
  • 28. Esse passo é muito importante. Nele vamos indicar o nome do subrelatório e como será referenciado pelo relatório principal. Como nosso relatório e o subrelatório podem mudar seus caminhos vamos dizer para o iReport que o caminho para o subrelatório será passado através de um parâmetro chamado SUBREPORT_DIR. O subrelatório deve ter uma aparência semelhante a que se encontra na imagem acima. Fiz apenas alguma modificações nas larguras dos textFields.
  • 29. Observem como está a query do relatório. Logo mais, o número 1 será modificado por um parâmetro. Voltando ao relatório principal, vamos agora modificar algumas configurações do subrelatório. Clique duas vezes em cima dele.
  • 30. Na aba Sub-Relatório (Outro) podemos observar que o iReport se encarregou de configurar o caminho para o subrelatório concatenando o seu nome com o diretório passado por parâmetro ($P{SUBREPORT_DIR}). Vamos agora passar um parâmetro do relatório principal para o subrelatório que servirá para fazer a query listando os professores de um determinado aluno. Clique no botão Adicionar. Na janela a seguir, digite idAluno no Nome de Parâmetro do Sub-Relatório. Depois clique no botão do lado direito (marcado na cor vermelha).
  • 31. Na expressão, digite $F{idAluno}. Clique em Aplicar. Com essa configuração, estamos dizendo para o JasperReports que para cada aluno colocado na tela, ele vai gerar um subrelatório que receberá como parâmetro o id do aluno que foi processado. Clique em OK.
  • 32. A tela deve ficar como a que está acima. Na aba Subrelatório, mude a Expressão de Conexão/Fonte de Dados de $P{subConnection} para $P{REPORT_CONNECTION}. Com isso você está dizendo para o JasperReports que a conexão com o banco de dados utilizada pelo subrelatório, está na chave REPORT_CONNECTION da lista de parâmetros.
  • 33. Voltando para o subrelatório, vamos agora mudar a Query do Relatório para poder receber o parâmetro passado e mostrar somente os professores do aluno correto. Entre novamente na opção Query do Relatório do menu Data. Mude o valor ‘1’ que tinha antes para $P{idAluno}, o parâmetro que está vindo do relatório principal. Clique em OK.
  • 34. Vamos agora preparar o subrelatório para receber o parâmetro do relatório principal. Entre na opção Parâmetros do Relatório, no menu Visualizar. Na aba Parâmetros, clique no botão Novo.
  • 35. Coloque o nome do parâmetro idAluno e informe que é do tipo Integer. Clique em OK. Salve os dois relatórios e mande compilar.
  • 36. 4.3.1 Código Java da Solução private ArrayList<Aluno> getListaAlunos(Connection conexao) throws SQLException { return (ArrayList<Aluno>) new AlunoDao().loadAll(conexao); } public String geraRelatorioPassandoListaDeObjetos() { saida = null; String jasper = getDiretorioReal("/jasper/professores_por_aluno_com_lista.jasper"); Connection conexao = null; try { // Conexão com o banco para o segundo relatório conexao = new Conexao().getConexao(); // criação dos parametros Map<String, Object> map = new HashMap<String, Object>(); // conexão com o banco que será utilizada pelo subrelatório map.put("REPORT_CONNECTION", conexao); // pego o caminho do diretório onde se encontra o subrelatório map.put("SUBREPORT_DIR", getDiretorioReal("/jasper/") + "/"); ArrayList<Aluno> alunos = getListaAlunos(conexao); JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(alunos); /* * Mando o jasper gerar o relatório. Nesse caso passo o map, * já que ele tem dois parâmetros que serão utilizados */ JasperPrint print = JasperFillManager.fillReport(jasper, map, ds); // Gero o PDF preenchePdf(print); } catch (Exception e) { e.printStackTrace(); } return "exibeRelatorio"; } Observe que no caso de passarmos uma lista, devemos encapsulá-la na classe JRBeanCollectionDataSource.
  • 37. 5. TESTES DE DOCUMENTOS COM SUBRELATÓRIOS Um grande problema com o qual me deparei quando comecei a usar o iReport foi o de realizar testes quando o relatório principal possuía uma subrelatório. Isso porque o subrelatório é referenciado pelo JasperReports através do parâmetro SUBREPORT_DIR e quando mandamos executar o relatório principal - caso você não efetue a configuração a seguir - o subrelatório não é encontrado. Para contornar isso, realizaremos uma configuração adicional, conforme as telas a seguir (o exemplo abaixo se aplica no exemplo de relatório com listas explicado no subcapítulo 4.3): Entre nos parâmetros do relatório principal, escolha SUBREPORT_DIR e clique em Modificar.
  • 38. Em Valor Padrão da Expressão, coloque o caminho para o diretório onde se encontra o arquivo jrxml do subrelatório. Agora clique em Executar relatório (usar conexão ativa).
  • 39. A tela a seguir será exibida. Clique em Usar padrão. Pronto! O relatório principal foi gerado executando a consulta no banco e o subrelatório funcionou com a mesma conexão utilizada pelo relatório principal. Observe que cada aluno tem sua lista de professores.
  • 40. 6. CONFIGURAÇÕES ÚTEIS 6.1 Configurações de textFields As configurações a seguir se aplicam quando se faz a operação a seguir: Clique com o botão direito sobre o textField e escolha a opção Propriedades 6.1.1 Campo deve ficar em branco quando for nulo Marque a opção Em branco quando for nulo da aba Campo texto.
  • 41. 6.1.2 Valor do campo não aparece quando ultrapassa o limite de espaço Marque a opção Imprimir quando detalhes excederem na aba Comum. 6.1.3 Campo deve crescer de acordo com o valor a ser exibido Marque a opção Aumentar quando exceder na aba Campo texto.
  • 42. 6.1.4 Campo deve ser exibido com formatação HTML Marque a opção HTML no item Markup da aba Fonte.