Thursday, April 26, 2018

Relatórios Utilizando Bean Datasource (parte 1)

JasperReports é uma biblioteca open-source de classes Java cuja finalidade é ajudar desenvolvedores com a tarefa de criar e adicionar rotinas de geração de relatório nas aplicações. Enquanto que o JasperStudio é uma aplicação que provê recursos visuais de alto nível drag and drop para agilizar a criação de relatórios utilizando o JasperReports.



As fontes de dados de um relatório podem ser as mais diversas, um arquivo xml, banco de dados, uma planilha, arquivos json. A mais comum em aplicações comerciais talvez seja as tabelas de um banco de dados relacional. Neste exemplo criamos um relatório que utiliza como fonte da dados os campos de um POJO (Plain Old Java Object) que adere às especificações JavaBeans (link) carregado na memória.

No nosso exemplo teremos um objeto Empresa que possui um conjunto de funcionários. Instanciamos a Empresa bem como seus funcionário e exibimos sob a forma de um relatório.

Utilizando a IDE Eclipse crie um novo projeto Maven. Vá em File/New/Other... na janela que abrir escolha Maven Project:


Clique em Next. Na próxima janela marque Create a simple project:


Clique em Next. Dê o nome ao seu projeto de ReportBeanDataSourceExample conforme a imagem abaixo e clique em finish:


No projeto, crie o pacote entidades e em seguida as classes Empresa e Funcionario.
package entidades;

import java.util.HashSet;
import java.util.Set;

public class Empresa {

 private String nome;
 private String cnpj;
 private Set<Funcionario> funcionarios = new HashSet<>();
 
 public Empresa(String nome, String cnpj) {

  super();
  this.nome = nome;
  this.cnpj = cnpj;
 }

 //getters e setters omitidos...
E a classe Funcionario:
package entidades;

public class Funcionario {

 private String nome;
 private String cpf;
 
 public Funcionario(String nome, String cpf) {

  super();
  this.nome = nome;
  this.cpf = cpf;
 }

 //getters e setters omitidos...
Tanto Empresa como Funcionario fazem parte do nosso modelo de negócios. Porém não serão essas classes efetivamente nossa fonte de dados, POJO. A nossa fonte de dados será um composition dessas duas classes e vamos definir nela apenas os métodos getters que queremos que seja exibido no relatório. Neste caso queremos um relatório que exiba o nome e o cnpj da empresa logo no começo, e nas próximas linhas liste os funcionário apresentando o nome e o cpf de cada um em duas colunas.

Uma vez definidos os requisitos, vamos criar nosso Bean Datasource. Vamos chamar essa classe de RelatorioFuncionariosBean:
package relatorios.bean;

import java.util.Set;
import entidades.Empresa;
import entidades.Funcionario;

public class RelatorioFuncionariosBean {

 private Empresa empresa;

 public RelatorioFuncionariosBean(Empresa empresa) {
  
  if(empresa == null)
   throw new NullPointerException("Empresa não pode ser null.");

  this.empresa = empresa;
 }
 
 public String getNomeEmpresa() {

  return empresa.getNome();
 }
 
 public String getCnpjEmpresa() {

  return empresa.getCnpj();
 }
 
 public Set<Funcionario> getFuncionarios() {

  return empresa.getFuncionarios();
 } 
}
As classes da biblioteca JasperReports descobre os valores dos campos invocando os métodos getters em cada classe, para isso é importante que suas classes sigam o padrão JavaBeans.

Adicionando no Projeto a Biblioteca JasperReport

Para exibir com sucesso nosso relatório, precisamos adiconar as bibliotecas JasperReports e a JasperFonts. Abra seu arquivo pom.xml e adicione as coordenadas das biblioteca conforme segue. Adicione também uma propriedade para que o Maven compile seu código de acordo com a versão 8 do Java:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>ReportBeanDataSourceExample</groupId>
  <artifactId>ReportBeanDataSourceExample</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <properties>
 <maven.compiler.source>1.8</maven.compiler.source>
 <maven.compiler.target>1.8</maven.compiler.target>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
   <dependency>
  <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports-fonts</artifactId>
    <version>6.0.0</version>
   </dependency>
   <dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports</artifactId>
    <version>6.5.0</version>
   </dependency>
  </dependencies>
</project>
Agora utilize as teclas de atalho ALT + F5 para que o Maven atualize seu projeto e importe as bibliotecas que você especificou no arquivo pom.xml.

Quando você trabalha com a biblioteca JasperReports, o primeiro passo é criar um arquivo template .xml contendo todos os elementos do relatório. Quando terminar de construir essa template, o relatório deve ser compilado para um arquivo .jasper, é esse arquivo que a aplicação java, por meio das classes da biblioteca JasperReports, utliza para construir o relatório preenchendo os campos com a fonte de dados. As classes da biblioteca Jasper ficam se ramificam a partir do pacote net.sf.jasperreports.

Crie um pacote main no seu projeto. Dentro dele, a classe Main.java. Crie também um pacote chamado imagem e cole nele alguma imagem qualquer para representar a logomarca da empresa.

Main.java
package main;

import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import entidades.Empresa;
import entidades.Funcionario;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRAbstractBeanDataSource;
import net.sf.jasperreports.engine.data.JRBeanArrayDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.view.JasperViewer;
import relatorios.bean.RelatorioFuncionariosBean;

public class Main {

 public static void main(String[] args) throws Exception {  
  
  //fonte de dados
  Empresa empresa = selectEmpresa();

  //Data Object
  RelatorioFuncionariosBean dadosDoRelatorio = new RelatorioFuncionariosBean(empresa);

  //obtem o arquivo compilado do relatório 
  InputStream arquivoJasper = Main.class.getResourceAsStream("/relatorios/relatorioFuncionarios.jasper");
  
  //JRAbstractBeanDataSource representa a fonte dados do relatório, passamos o objeto 'dadosDoRelatorio' no construtor
  JRAbstractBeanDataSource dataSource = new JRBeanArrayDataSource(new RelatorioFuncionariosBean[] {dadosDoRelatorio});
  
  JRAbstractBeanDataSource funcionarios = new JRBeanCollectionDataSource(empresa.getFuncionarios());
  
  //qualquer parâmetro dinâmico do relatório, a logomarca da empresa por exemplo...
  Map<String, Object> parametrosRelatorio = new HashMap<>();
  parametrosRelatorio.put("LOGOMARCA", Main.class.getResourceAsStream("/imagem/acme.jpg"));
  parametrosRelatorio.put("FuncionariosDataSource", funcionarios);
  
  //JasperPrint representa o arquivo do relatório, fillReport() carrega o relatório a partir do InputStream 
  JasperPrint jasperPrint = JasperFillManager.fillReport(arquivoJasper, parametrosRelatorio, dataSource);
  
  //JasperViwer extende javax.swing.JFrame para exibir o relatório
  JasperViewer jasperViewer  = new JasperViewer(jasperPrint);
  jasperViewer.setVisible(true);
 }

 private static Empresa selectEmpresa() {
  
  Empresa empresa = new Empresa("ACME Corporation S/A", "12345678999-78");
  List<Funcionario> funcionarios = Arrays.asList(new Funcionario("Danilo Levi", "22222222222"),
          new Funcionario("Yasmim Marlene", "33333333333"),
          new Funcionario("Francisca Lucia", "33333333333"),
          new Funcionario("Livia Sabrina", "44444444444"),
          new Funcionario("Rafael Lago", "55555555555"),
          new Funcionario("Heitor Augusto", "66666666666"),
          new Funcionario("Caleb Luis", "77777777777"),
          new Funcionario("Luiza Costa", "88888888888"));
  empresa.setFuncionarios(new HashSet<>(funcionarios));  
  return empresa;
 }
}
A aplicação está pronta. Agora precisamos desenhar o relatório, compila-lo e colar o arquivo relatorioFuncionarios.jasper no pacote relatorios. Faremos isso com o JasperStudio na Parte 2 deste artigo.

       

No comments:

Post a Comment