Olá Pessoal, tudo bom?
No artigo de hoje iremos passar uma lista de instâncias de uma classe DTO como field para um relatório Jasper. Veja na continuação.
Antes de continuar a leitura…
Nesse artigo utilizamos o pattern DTO. Se você não sabe o que significa DTO, por favor leia o artigo.
Explicando como será o envio desta Lista de EnderecoDTO
Para enviar parâmetros ao Jasper Reports, cada parâmetro deverá ser criado individualmente. O tratamento para enviar Fields ao Jasper Reports é diferente, pois existem 3 pontos importantes para funcionar corretamente:
No primeiro ponto, o desenvolvedor deve criar um field para cada atributo interno da classe que está contida na lista. Por exemplo, ao enviarmos uma lista de EnderecoDTO deverá ser criado fields para cada atributo que nesse DTO, ou aqueles que você deseja exibir em tela. Assim para o exemplo do EnderecoDTO deverão ser criados 7 fields, um para cada atributo do EnderecoDTO.
Segundo ponto é que os fields deverão ser usados dentro da band Detail, pois conforme explicado nesse artigo, essa band possui uma estrutura de repetição interna própria para Listas passadas como fields.
Terceiro ponto, ao enviar essa lista no Java deverá ser enviado via JRDataSource e não o Map de parâmetros que enviávamos anteriormente.
Explicado isso vamos apresentar cada ponto.
Parte 1 – Criando um Field no JasperSoft Studio
Acesse a aba Outline e clique com o botão direito do mouse no item Fields e acesse a opção Create Field, conforme mostra a Figura 01
Será criado um novo field com o nome Field_1, conforme mostra a Figura 02
Clique sobre o novo field e acesse a aba Properties, Figura 03. Algumas informações já virão preenchidas como Name e Class.
Agora é o ponto mais importante na criação de um field, pois devemos modificar o name e o class para os mesmos nome e tipo de classe que se encontram no DTO que queremos informar, o campo name deve ser igual ao nome do atributo, incluindo nesse ponto letras maiúsculas e minusculas. Dessa forma, supondo que criaremos o field numero, deve ser mudado o name para “numero” e o class para java.lang.Integer, como mostra a Figura 04. Com isso na aba Outline ocorrerá uma mudança no nome do field.
Agora você deverá criar da mesma forma outros fields para os atributos que estão no DTO. Conforme lista abaixo:
- Atributo bairro:
- name bairro
- class java.lang.String
- Atributo cidade:
- name cidade
- class java.lang.String
- Atributo complemento:
- name complemento
- class java.lang.String
- Atributo estado:
- name estado
- class java.lang.String
- Atributo pais:
- name pais
- class java.lang.String
- Atributo rua:
- name rua
- class java.lang.String
Parte 2 – Utilizando o field no relatório
Após a criação dos fields, é a hora de utilizá-los no relatório. Conforme descrito anteriormente, a band Detail possui uma estrutura interna de repetição, o qual obtém a lista passada no Java e pega elemento a elemento, jogando os valores do elemento atual nos fields criados. Caso não haja um field criado no elemento ocorrerá um erro de parser do jasper. Assim vamos criar um Text field element, que está localizado na aba Palette, conforme mostra a Figura 05.
Agora clique sobre o elemento Text Field e arraste-o para a band Detail do relatório. Deverá aparecer um elemento dentro dessa área como mostra a Figura 06
Com o elemento criado, de um duplo clique nele. O Jaspersoft irá abrir uma popup chamada Expression Editor com o texto que está atualmente no elemento “Text Field”, como mostra a Figura 07.
Um ponto importante aqui é que o text área superior, a expressão propriamente dita segue os padrões do Java, ou seja, o campo é uma String, logo o retorno dessa expressão tem q ser uma String. Se você escrever Text Field sem aspas duplas ocorrerá um erro.
Agora clique na propriedade Fields, localizada na primeira coluna, serão exibidos todos fields existentes nesse relatório (segunda coluna), conforme mostra a Figura 08.
Na segunda coluna selecione o field criado, numero. De um duplo clique sobre este e ele aparecerá no padrão jasper ($F{numero}) na expressão, conforme mostra a Figura 09.
O problema é que agora ocorreu um erro “The current expression is not valid. Please verify it”. Isso ocorre porque a expressão não está de acordo com os padrões necessários para a expressão de um Text Field, ou seja, retornando uma String. Para arrumar essa expressão, vamos inverter a ordem conforme o código abaixo e a Figura 10.
1 |
"Número: " + $F{numero} |
Agora clique em Finish, a popup irá fechar e o conteúdo da expressão irá aparecer no Text Field do relatório, conforme Figura 11.
Adicione outros text fields elements para representar os outros fields criados anteriormente. As expressões estão em ordem alfabética por atributo:
- Atributo bairro: “Bairro: ” + $F{bairro}
- Atributo cidade: “Cidade: ” + $F{cidade}
- Atributo complemento: “Complemento: ” + $F{complemento}
- Atributo estado: “Estado: ” + $F{estado}
- Atributo pais: “País: ” + $F{pais}
- Atributo rua: “Rua: ” + $F{rua}
Por fim é bom ter em mente que o tamanho desses campos variam muito pois são dinâmicos. Nesse momento uma boa prática é testar o campo com o seu tamanho máximo, para já prever problemas que podem acontecer ao gerar textos grandes no relatório. Isso normalmente ocorre com o cliente e temos de corrigir com uma grande rapidez. Então evite isso 🙂
Agora salve esse relatório (Ctrl + s) e compile-o (duvida? veja aqui). Copie os arquivos .jrxml e o .jasper para o diretório onde estão localizados os relatórios no projeto Java do Eclipse, para podermos gerar esse relatório via código.
Parte 3 – Criando a Lista de DTOs para enviar ao Jasper via Java
O software agora muda, vamos voltar ao Eclipse e mexer com o código Java. Se você, caro leitor, seguiu os passos desse tutorial de configuração do projeto Maven com o Jasper, provavelmente você tenha em seu projeto uma classe Java de teste para ser executada via JUnit. O código desta classe está no quadro abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package br.com.mauda.SeminariosCientificos; import org.junit.Test; import net.sf.jasperreports.engine.JREmptyDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; /** * Unit test for simple App. */ public class AppTest{ @Test public void teste() throws JRException{ //Obtem o valor atual do sistema long inicioContagem = System.currentTimeMillis(); //Compilacao no formato jasper para o jrprint JasperFillManager.fillReportToFile("reports/relatorioTeste.jasper", null, new JREmptyDataSource(1)); System.err.println("Tempo de compilacao jasper -> jrprint: " + (System.currentTimeMillis() - inicioContagem)); //Reinicia o contador inicioContagem = System.currentTimeMillis(); //Geracao do PDF JasperExportManager.exportReportToPdfFile("reports/relatorioTeste.jrprint"); System.err.println("Tempo de geracao do PDF: " + (System.currentTimeMillis() - inicioContagem)); } } |
Agora vamos modificar essa classe com novos itens, para que possamos adicionar uma lista de EnderecoDTO e gerar o novo relatório criado via Jaspersoft Studio. Para tanto vamos criar um método que retorna uma Collection<EnderecoDTO> (linhas 18-31). Na linha 38 chamamos esse método para obter essa lista. Na linha 41 modificamos a passagem de informações fields, criando um novo DataSource, um JRBeanCollectionDataSource, que recebe a collection de enderecosDTO e um false como a descrição da collection informada. Assim com essas modificações o código fica desta maneira:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package br.com.mauda.SeminariosCientificos; import java.util.ArrayList; import java.util.Collection; import org.junit.jupiter.api.Test; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; /** * Unit test for simple App. */ public class AppTest { private Collection<EnderecoDTO> getEnderecos() { Collection<EnderecoDTO> enderecos = new ArrayList<>(); for (int i = 0; i < 10; i++) { EnderecoDTO enderecoDTO = new EnderecoDTO(); enderecoDTO.setRua("Rua " + i); enderecoDTO.setNumero(10 + i); enderecoDTO.setComplemento("Apto " + i); enderecoDTO.setBairro("Bairro " + i); enderecoDTO.setCidade("Cidade " + i); enderecoDTO.setEstado("Estado " + i); enderecoDTO.setPais("Pais " + i); } return enderecos; } @Test public void teste() throws JRException { // Obtem o valor atual do sistema long inicioContagem = System.currentTimeMillis(); Collection<EnderecoDTO> enderecos = this.getEnderecos(); // Compilacao no formato jasper para o jrprint JasperFillManager.fillReportToFile("reports/relatorioTeste.jasper", null, new JRBeanCollectionDataSource(enderecos, false)); System.err.println("Tempo de compilacao jasper -> jrprint: " + (System.currentTimeMillis() - inicioContagem)); // Reinicia o contador inicioContagem = System.currentTimeMillis(); // Geracao do PDF JasperExportManager.exportReportToPdfFile("reports/relatorioTeste.jrprint"); System.err.println("Tempo de geracao do PDF: " + (System.currentTimeMillis() - inicioContagem)); } } |
Agora é executar o código via JUnit e ver surgir um arquivo pdf com o10 enderecos sendo mostrados pelo Jasper no arquivo pdf.
finally{
Assim terminamos a descrição sobre como criar e enviar fields para um relatório.
Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!
Até um próximo post!
Leave a Reply