Se analisarmos um ponto importante na maioria dos sistemas, sejam eles complexos ou simples, o objetivo final é quase sempre disponibilizar ao usuário/cliente um grande leque de relatórios para que este possa então tomar a decisão correta, vamos a alguns exemplos:

  1. Um sistema de prevenção de desastres naturais captura dados geográficos para então gerar relatórios periódicos que possam dizer aos meteorologistas prováveis catástrofes que venham a ocorrer em um futuro próximo, cabe a estes analisar e tomar a decisão para tal fato.
  2. Um sistema de vendas (PDV) aparentemente só tem a função de vender e emitir documentos fiscais e não fiscais através de uma ECF (Emissor de Cupom Fiscal), mas vai muito além disso, o simples ato de emitir um documento seja em uma Impressora Fiscal (ECF) ou em uma Impressora comum (jato de tinta) já caracteriza a emissão de um relatório.
  3. Existem sistemas especializados em apenas coletar dados de outros sistemas e gerar relatórios. Alguns relatórios chegam a apresentar propostas tão complexas que são necessários Sistemas a parte para o controle destes.

Vejamos o significado da palavra relatório no dicionário: “Um relatório é uma exposição escrita, minuciosa e circunstanciada relativa a um assunto ou fato ocorrido. O objetivo de um relatório é comunicar uma atividade desenvolvida ou ainda em desenvolvimento durante uma missão. Deve fornecer o relato permanente de um estudo ou de uma pesquisa e a informação necessária, que deve ser global e coerente, capaz de permitir tomadas corretas de decisões.”

Conheça a formação programador Java da DevMedia, o seu índice de aprendizado em Java

Conseguiu assimilar? Relatório é qualquer exposição escrita e isso nos remete a qualquer tipo de impressão realizada no Sistema A,B ou C.

Agora que já estamos familiarizados com o conceito de relatório, podemos prosseguir a assuntos mais técnicos que dizem respeito a tecnologias especificas utilizadas para geração de tal artefato tão importante em nosso dia a dia.

Relatórios em Java

Tratando-se de relatórios em Java, JasperReport é o nome da nossa solução. Este é um poderoso framework open-source escrito em Java que permite a geração de relatórios em diversos formatos e com muitos recursos (PDF, HTML, XLS, CSV e XML). Assim como Java tem frameworks para outras tarefas como: Banco de Dados (Hibernate), Injeção de Dependência (CDI, Spring Framework), Controle de Bibliotecas e suas dependências (Maven) e muitos outros, o Java também tem um framework para geração de relatórios.

Os arquivos de relatórios gerados pelo JasperReport tem o formato “.jasper” e seu conteúdo é em XML, é nele que todas as dimensões, campos, e todas as as características do relatório são postas.

Agora imagine se você tivesse que criar todo o relatório apenas com código XML, sem nenhuma ferramenta para desenhar, seria muito complexo e pouco produtivo. Para isso usaremos o iReport que é uma IDE para “desenharmos” o relatório que será gerado em formato “jasper”.

Para quem está um pouco mais habituado a construção de formulários em Java, iremos fazer uma analogia com estes para que você possa assimilar melhor a diferença entre o JasperReport e o iReport (que muito se confunde entre os profissionais da área).

Quando você vai construir formulários em Java provavelmente usa AWT, Swing ou SWT, certo? Acontece que raramente ou quase nunca você vai direto no código e começa a criar os componentes e dispor eles em determinadas coordenadas, seria muito difícil e complexo, além muito muito pouco produtivo. Normalmente você abre uma IDE e constrói todo seu formulário com uma ferramenta “drag-and-drop”, netbeans ou eclipse por exemplo.

Depois que você constrói todo seu formulário facilmente com uma IDE que tem o recurso “drag-and-drop” é gerado um classe no formato “.java” com todo aquele código que você teria que digitar na mão, sua tarefa agora é colocar ações nos botões e dar vida aquela tela que antes não tinha função alguma.

Enfim, o processo de construção de relatório em Java é similar ao que foi explicado acima, onde o JasperReport seria nosso AWT, Swing ou SWT e o Netbeans ou Eclipse seria nosso iReport.

Lembra que falamos que o JasperReport gera um arquivo “jasper” certo? O iReport também gera seu próprio arquivo, um “.jrxml”. Novamente fazendo uma analogia, assim como o netbeans gera nosso “.form” o iReport gera o “.jrxml” para que possamos alterar o “desenho” do relatório a qualquer momento, mas independente da IDE que você use para fazer o “desenho” do relatório o objeto sempre será o mesmo, um arquivo “jasper”.

Instalando o JasperReport no seu Projeto

Partindo do princípio que você está utilizando um gerenciador de dependências/bibliotecas necessárias, em nosso caso o Maven, iremos mostrar os arquivos necessários para funcionamento e uso do JasperReport em nosso projeto. Observe a Listagem 1.

Listagem 1. pom.xml para JasperReport


  <dependency>
        <groupId>org.apache.poi</groupId>
         <artifactId>poi</artifactId>
         <version>3.10-FINAL</version>
  </dependency>
   
  <dependency>
       <groupId>net.sourceforge.barbecue</groupId>
       <artifactId>barbecue</artifactId>
       <version>1.5-beta1</version>
  </dependency>
   
  <dependency>
       <groupId>net.sf.jasperreports</groupId>
       <artifactId>jasperreports</artifactId>
       <version>5.0.1</version>
  </dependency>
  

<dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports-fonts</artifactId>
        <version>4.0.0</version>
  </dependency>
   
  <dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        <version>2.10.0</version>
  </dependency>

Se você não usa o Maven, pode optar por baixar os “.jars” sem importa-los no classparth do seu projeto. Vamos explicar para que serve cada uma das bibliotecas acima:

  1. Apache POI: Usado para exportar seus relatórios para formatos suportados pelo “Microsoft Office”, tais como excel, word e powerpoint.
  2. Barbecue: Usado para criação de código de barras, muito usado em relatórios que serão lidos com leitores de código de barras.
  3. JasperReport: Como sendo nossa principal biblioteca, é responsável por gerar o relatório em si, utilizando as ferramentas auxiliares apresentadas em nosso pom.xml.
  4. JasperReport-fonts: Como o próprio nome sugere, fontes para o JasperReport.
  5. xerces: É um conjunto de bibliotecas para validação, serialização e manipulação de XML.

Com as importações necessárias realizadas você já pode fazer uso do JasperReport e suas bibliotecas auxiliares afim de gerar um relatório completo e repleto de informações.

Entendendo o JasperReport

É importante entender o funcionamento do JasperReport antes de iniciar o desenho de um relatório com o iReport, isso porque pode ser que em algum momento seja necessário alterar diretamente informações no XML, e conhecer sua estrutura é essencial.

Campos, Parâmetros e Variáveis

No JasperReport você irá se deparar com três conceitos bases, que são: Campos (field), Parâmetros(parameter) e Variáveis (variable).

Os campos/fields são utilizados para mapear dados diretamente a colunas no banco de dados ou a classes Java, se você estiver trabalhando com um mapeamento, eles surgem através da sua fonte de dados. Vejamos a Listagem 2.

Listagem 2. Exemplo de field


  <field name=”nomeCompleto” class=”java.lang.String”/>

O que temos acima é a criação do campo “nomeCompleto”, que provavelmente é um método “getNomeCompleto()” na nossa classe Java.

Os parâmetros/parameter, ao contrário dos campos, não vem de uma fonte de dados. Estes são passados para preencher algum valor no relatório, tal como: título do relatório, endereço da empresa e etc. Vejamos um exemplo na Listagem 3.

Listagem 3. Exemplo de parameter


  <parameter name=”NomeDoRelatorio” class=”java.lang.String”/>

Em Java, podemos fazer o uso da classe Map para realizar a passagem de parâmetros ao Jasper. Observe um exemplo na Listagem 4.

Listagem 4. Passando parâmetros ao Jasper via Java


  Map parametros = new HashMap( );
  parametros.put( “NomeDoRelatorio”, “REL001 – DESPESAS MENSAIS” );

As variáveis/variables são usadas internamente no relatório, diferente dos campos e parâmetros que vem de uma fonte externa. As variáveis são utilizadas para cálculos como: contagem (count), soma (sum), média (average), menor (lowest), maior (highest) e etc. São valores temporários apenas para cumprir determinada tarefa específica no relatório. Observe um exemplo na Listagem 5.

Listagem 5. Exemplo de variable


  <variable name=”totalVendido” class=”java.lang.Double”    calculation=”Sum”>
         <variable expression> ${valorVenda} </variable expression>
  </variable>

No exemplo acima estamos somando os valores de ${valorVenda} de cada registro e armazenando na variável “totalVendido”.

O próprio JasperReport já conta com algumas variáveis internas para evitar retrabalho, são elas: PAGE_NUMBER, COLUMN_NUMBER, REPORT_COUNT, PAGE_COUNT e COLUMN_COUNT. Todas são bem explicativas e dispensam comentários.

Além disso, o recurso de variáveis ainda tem algumas peculiaridades. Podemos, por exemplo, definir o valor de inicialização da variável e quando ela será inicializada, como podemos ver na Listagem 6.

Listagem 6. Inicializando variável


  <variable name=totalVendido class=”java.lang.Double” resetType=”Page” calculation=”Sum”>
         <variable expression> ${valorVenda} </variable expression>
         <initialValueExpression> new Double( 0 ) </initialValueExpression>
  </variable>

Acima estamos definindo que a variável irá ser inicializada com o valor “0”, mas quando ela será inicializada? Em nosso caso definimos o valor “Page” que diz ao JasperReport para inicializar a variável a cada página.

Expressões / Expressions

As expressões são utilizadas para formatar o conteúdo de um campo de texto (estático) de forma que este possa possuir valores dinâmicos, são utilizadas expressões Java para montar tal conteúdo, o que torna mais fácil a utilização deste. Vejamos um exemplo na Listagem 7.

Listagem 7. Usando expressions


  <textFieldExpression>
      "A Nota foi emitida em "+(new SimpleDateFormat("dd/MM/yyyy")).format($F{dataEmissao})+ " pelo usuário "+$F{nomeUsuario}+
      " no valor total de "+$V{totalVendido}
  </textFieldExpression>

Perceba acima que usamos fields ($F{}) e variables ($V{}) para montar nossa mensagem dinâmica, de forma a mostrar informações mais relevantes ao usuário. Você perceberá ao longo da construção de um relatório que as expressões são usadas demasiadamente para tornar o relatório mais apresentável ao usuário final.

Layout

Estudamos acima a utilização de dados no JasperReport (campos, parâmetros, variáveis e expressões). Precisamos agora entender como o Jasper organiza/dispõe tais dados na sua página.

Há uma divisão de áreas no relatório, que são chamadas de “seções”, são elas: background, title, pageHeader, columnHeader, detail, columnFooter, pageFooter, lastPageFooter e summary. Cada uma dessas seções tem suas especificidade, como por exemplo a “detail” é onde colocamos nossa fonte de dados.

API do JasperReport

Veremos agora algumas das classes utilizadas para geração de relatório com o Jasper e qual sua utilidade.

De acordo com a UFCG (Universidade Federal de Campina Grande) são listadas abaixo as classes e suas determinadas funcionalidades:

  • Classe dori.jasper.engine.design.JasperDesign: Instâncias dessa classe representam o relatório no seu formato mais primitivo. São resultados de um processamento sobre o arquivo XML.
  • Classe dori.jasper.engine.JasperReport: Instâncias dessa classe representam relatórios compilados. Nesse estágio, toda a análise sintática nas expressões existentes no XML já foram realizadas. Objetos dessa classe podem ser armazenados em arquivos “.jasper”.
  • Classe dori.jasper.engine.JasperCompileManager: Responsável por criar instâncias das classes JasperReport e JasperDesign.
  • Classe dori.jasper.engine.JasperPrint: Consiste no JasperReport com todos os campos preenchidos. Um objeto dessa classe pode ser visualizado diretamente utilizando visualizadores internos do JasperReport, como também pode ser transformado em formatos mais populares como HTML, XML ou PDF.
  • Interface dori.jasper.engine.JRDataSource: Essa interface padroniza o comportamento das classes que manipulam as fontes de dados necessárias durante o preenchimento dos campos existentes no JasperReport. Dessa forma, várias fontes podem ser utilizadas, seja um banco de dados, ou mesmo um arquivo XML.
    Entre as classes que implementam essa interface; podemos citar:
    • dori.jasper.engine.JRResultSetDataSource (acessa um banco de dados);
    • dori.jasper.engine.data.JRTableModelDataSource (acessa tabelas já carregadas em interfaces swing);
    • dori.jasper.engine.JREmptyDataSource (não acessa nenhuma fonte de dados, utilizada quando se deseja criar um JasperPrint sem acessar nenhuma fonte de dados).
  • Classe dori.jasper.engine.JasperFillManager: Essa classe é utilizada para gerar instâncias da classe JasperPrint. Em seu processamento, ela utiliza uma fonte de dados (JRDataSource) e uma instância da classe JasperReport.
  • Classe dori.jasper.engine.JasperPrintManager: Permite imprimir o relatório (o conteúdo do relatório é enviado para impressora, uma janela de requisição de impressão é aberta). Tanto é possível imprimir todo o relatório como também páginas do mesmo.
    Além disso, é possível imprimir o relatório como uma imagem (utilizando o método printPageToImage)
  • Classe dori.jasper.engine.JasperExportManager: Permite gerar documentos nos formatos PDF, HTML e XML (versão 1.0). Com o tempo, novos formatos serão incorporados.

Listagem 8. Exemplo completo de JasperReport


 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.HashMap;
 import java.util.Map;
 import net.sf.jasperreports.engine.JRException;
 import net.sf.jasperreports.engine.JRResultSetDataSource;
 import net.sf.jasperreports.engine.JasperCompileManager;
 import net.sf.jasperreports.engine.JasperFillManager;
 import net.sf.jasperreports.engine.JasperPrint;
 import net.sf.jasperreports.engine.JasperReport;
 import net.sf.jasperreports.engine.design.JasperDesign;
 import net.sf.jasperreports.engine.xml.JRXmlLoader;
 import net.sf.jasperreports.view.JasperViewer;
 
 public class JasperReportExemple {
 
 private static final String url = "jdbc:mysql://127.0.0.1/teste";
 private static final String driver = "com.mysql.jdbc.Driver";
 private static final String login = "";
 private static final String pwd = "";
 
 public JasperReportExemple() {
 }
 
 public void gerar( String layout ) throws JRException , SQLException, ClassNotFoundException {
 //gerando o jasper design
 JasperDesign desenho = JRXmlLoader.load( layout );
 
 //compila o relatório
 JasperReport relatorio = JasperCompileManager.compileReport( desenho );
 
 //estabelece conexão
 Class.forName( driver );
 Connection con = DriverManager.getConnection( url , login , pwd );
 Statement stm = con.createStatement();
 String query = "select * from turma";
 ResultSet rs = stm.executeQuery( query );
 
 //implementação da interface JRDataSource para DataSource ResultSet
 JRResultSetDataSource jrRS = new JRResultSetDataSource( rs );
 
 //executa o relatório
 Map parametros = new HashMap();
 parametros.put("nota", new Double(10));
 JasperPrint impressao = JasperFillManager.fillReport( relatorio , parametros, jrRS );
 
 //exibe o resultado
 JasperViewer viewer = new JasperViewer( impressao , true );
 viewer.show();
 }
 
 public static void main(String[] args) {
 try {
 new JasperReportExemple().gerar( "report.jrxml" );
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 }

O que temos na Listagem 8 é a geração de um relatório salvo no arquivo “report.jrxml”, já desenhado através do iReport.

Agora que temos conhecimento do principal, que é o uso do JasperReport em Java, podemos começar a apresentar a ferramenta iReport para que você possa desejar seu relatório. Você irá perceber que ela é bem intuitiva e de fácil utilização, vamos apresentar algumas de suas principais características.

Introdução ao iReport

Utilizamos para demonstração o iReport versão 5.5.0, como mostra a Figura 1.

Apresentação do iReport

Figura 1. Apresentação do iReport

Temos na Figura 1 três áreas primordiais para construção do seu relatório. A área 1 possui o conteúdo do relatório em si, ou seja, campos, parâmetros, variáveis, seções, estilos e etc. Quando você adiciona um field no seu relatório, é nesta área que você poderá encontrá-lo para realizar as configurações necessárias. Quando você deseja ocultar, adicionar ou deletar uma seção (detail, title, summary e etc) é nesta área que você o faz.

Na área 2 temos o desenho do relatório, ou seja, a conversão do arquivo JRXML para um ambiente gráfico, de forma que possamos ter uma melhor perspectiva de como será o resultado final do nosso relatório.

Por fim, na área 3 temos as saídas (mensagens) do iReport ao realizar a compilação do nosso relatório: Erros, Informações e etc.

Segunda parte iReport

Figura 2. Segunda parte iReport

Para finalizar, temos a área 1 na Figura 2 que corresponde a paleta de elementos que iReport disponibiliza, com ela nós podemos utilizar o famoso recurso “drag-and-drop” evitando ter que codificar em XML.

Na área 2 da Figura 2 temos as propriedades do elemento selecionado, em nosso caso selecionamos o elemento “StaticText” com o conteúdo “Ola Mundo” e podemos agora configurar suas propriedades como altura, largura, cor, fonte e etc.

Com isso concluímos esse artigo, onde tivemos uma visão geral do uso do JasperReport em Java com seus detalhes e peculiaridades e por fim vimos como usar o iReport para desenhar nosso relatório de forma rápida e fácil. Vale ressaltar que o uso do iReport é opcional, por ser apenas uma IDE para construção do relatório, assim como o Eclipse esta para o Java.