22 de maio de 2011

JasperReports 4.0.1: JavaBean datasource - abrir relatório em projeto desktop

Depois de vermos como chamar um relatório feito no JasperReports utilizando JavaBean, nessa postagem vamos usar o mesmo relatório mas em um projeto Java Desktop!
Reveja algumas postagens:

Começando...
Caso tenha seguido a postagem Utilizando JavaBean datasource(link acima) pule essa parte de criar um projeto, a classe Java e tals, pode-se utilizar o mesmo projeto feito lá. Caso contrário, vamos ver o que precisa ser feito:
Para começar, no NetBeans crie um novo Aplicativo Java com o nome de PrimeiroRelatorio.
Feito isso, vamos criar a estrutura que usamos para gerar o .jasper, então em Pacotes de código-fonte já existirá um pacote com o nome de primeirorelatorio e dentro dele crie um pacote model, dentro desse pacote crie a classe Produto (lembrando que tem que ser idêntica à aquela usada no .jar para gerar o relatório), ficando com esta estrutura:

Relembrando a classe Produto:
public class Produto {
    private int codigo;
    private String nome;
    private BigDecimal valor;

    //gerar getters e setters
}

Agora precisamos de um lugar para guardar nosso .jasper, para isso crie a seguinte estrutura de pacotes:
primeirorelatorio.controle.relatorios, e dentro dele, coloque o arquivo .jasper (no meu caso PrimeiroRelatorio.jasper):


Caso não tenha baixado as bibliotecas do JasperReports, baixe por aqui.
De todas as bibliotecas disponibilizadas no link, para este tipo de relatório iremos usar apenas algumas delas, acabei filtrando e chegando as que realmente precisavam, então adicione ao projeto as seguintes bibliotecas:


Como já criamos um pacote primeirorelatorio.controle.relatorios, já temos um pacote controle, e então dentro dele teremos uma classe Java com o nome de RelatorioControle:


O código fonte dessa classe será esse (abaixo do código eu explico ela):
package primeirorelatorio.controle;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.view.JasperViewer;
import primeirorelatorio.model.Produto;

/**
 *
 * @author andii
 */

public class RelatorioControle {

    public void gerarRelatorio() {
        String arquivo = "src/primeirorelatorio/controle/relatorios/PrimeiroRelatorio.jasper";

        JRDataSource jrds = new JRBeanCollectionDataSource(listarProdutos());

        gerarRelatorioDesktop(jrds, null, arquivo);
    }

    private void gerarRelatorioDesktop(JRDataSource jrds, Map<Object, Object> parametros, String arquivo) {
        try {
            JasperPrint print = JasperFillManager.fillReport(arquivo, parametros, jrds);
            JasperViewer.viewReport(print, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private List<Produto> listarProdutos() {
        List<Produto> produtos = new ArrayList<Produto>();
        Produto p1 = new Produto();
        p1.setCodigo(1);
        p1.setNome("Produto 1");
        p1.setValor(new BigDecimal(1.99));
        produtos.add(p1);

        Produto p2 = new Produto();
        p2.setCodigo(2);
        p2.setNome("Produto 2");
        p2.setValor(new BigDecimal(3000.50));
        produtos.add(p2);

        Produto p3 = new Produto();
        p3.setCodigo(3);
        p3.setNome("Produto 3");
        p3.setValor(new BigDecimal(500.00));
        produtos.add(p3);
        return produtos;
    }
}

Vamos ver o que esses métodos fazem: 

public void gerarRelatorio()
Inicialmente este método será chamado pela nossa classe Main (que foi criada por padrão no projeto), nesse método nós precisamos pegar o caminho exato do nosso arquivo .jasper, que lá no começo da postagem colocamos dentro do pacote primeirorelatorio.controle.relatorios para isso precisamos indicar o caminho corretamente.
Quanto ao jrds: por termos utilizado uma classe Java para gerar nosso .jasper, precisamos passar para nosso relatório um JRDataSource, que é formado por uma lista de Produto (pois o método listarProdutos(), retorna uma lista de produtos que poderia muito bem estar vindo de um banco de dados).
Ao chamar o gerarRelatorioDesktop, estamos passando um parâmetro null, esse corresponderia a uma Map, que serviria para passarmos parâmetros(que vai ficar pra outra postagem) para o nosso relatório...
Agora vamos ver o que acontece no:
gerarRelatorioDesktop(JRDataSource jrds, Map<Object, Object> parametros, String arquivo)
Dentro de um try-catch(para capturar possíveis exceções) nós temos o método principal que é o responsável por gerar o que vai ser o nosso relatório, que é essa linha aqui:
JasperFillManager.fillReport... 
esse método não cria um arquivo .pdf fisicamente no computador, apenas gera ele como se fosse um arquivo temporário, e quem decide se quer salvar o relatório ou não é o usuário, depois disso, chamamos o JasperViewer que é o que eu chamo de "visualizador de relatórios" do próprio JasperReports (ao final eu mostro visualmente este visualizador)...
Depois de vermos a principal classe do projeto, vamos ver a classe Main.java(dentro do pacote primeirorelatorio) que vai ser a responsável por mostrar uma telinha em Swing que tem um jButton, e que quando clicar nele ele vai chamar nosso método gerarRelatorio() da nossa classe RelatorioControle, veja o código da classe Main abaixo:
package primeirorelatorio;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import primeirorelatorio.controle.RelatorioControle;

/**
 *
 * @author andii
 */
public class Main {

    public static void main(String[] args) {
        JFrame frame = new JFrame("Meu relatorio!");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton botao = new JButton("Chamar meu relatório!");
        botao.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                RelatorioControle controle = new RelatorioControle();
                controle.gerarRelatorio();
            }
        });

        frame.getContentPane().add(botao);
        frame.pack();
        frame.setVisible(true);

    }
}
Ao executar o projeto (F6) temos a seguinte tela (é bem essa grande tela aí abaixo):


Ao clicar no botão "Chamar meu relatório!", ele irá fazer o que o próprio nome dele já diz: Chamar o nosso relatório =) ... assim, aparece a seguinte tela do JasperViewer:


Por aqui finalizamos a visualização de relatórios feito no JasperReports utilizando JavaBean. =)

6 comentários:

  1. na linha 44 da classe gerar relatorio, n consigo add o objeto da classe do Banco na qual : "produtos.add(p1)" na hora q tento adicionar esse "p1" da erro ! help me

    Obg.

    ResponderExcluir
  2. Que erro que dá? Veja no seu GlassFish, se for Nullpointer é porque a lista de produtos não foi instanciada

    ResponderExcluir
  3. nao sei se ainda respondem duvidas,mas tenho uma baita duvida, como fazer pra acessar campos de dados criados pelo usuario, por exemplo, Uma lista de respostas onde nessa lista possui um atributo pergunta do tipo Questao? Como faco para acessar esse atributo. se puder me explicar, a me enviar um exemplo ficaria mto grato.

    ResponderExcluir
    Respostas
    1. Pelo o que eu entendi, vc quer algo assim $F{cliente}.getNome() ... se estiver usando JavaBean datasource mesmo (os gets são de acordo com o que tiver de gets nas suas classes), dessa forma dá certo, realmente orientado a objetos.

      Excluir
    2. Muito obrigado, eu fiz exatamente como falou, acabei descobrindo na marra mesmo, mas foi mto bom ter encontrado esse site, sem ele nao teria conseguido criar os relatorios de que necessitava para minha aplicacao.

      Excluir
    3. funcionou dessa forma?

      Excluir

Deixe seu comentário... ;)