Olá Pessoal, tudo bom?
No artigo de hoje irei descrever como enviar parâmetros para um relatório, além de como utilizá-los em um relatório. Acompanhe na continuação. O artigo será dividido em três frentes, a primeira irá criar o parâmetro dentro do Jaspersoft Studio, após a utilização desse parâmetro em um campo do relatório, por fim o código java que envia esse parâmetro ao Jasper e obtém o pdf final com o parâmetro.
Parte 1 – Criando parâmetro no Jaspersoft Studio
Para começar vamos continuar com um relatório blank_A4, conforme os passos descritos nesse artigo para sua criação. Você deverá ter uma tela muito parecida com a Figura 01.
Agora acesse a aba Outline e clique com o botão direito do mouse no item Parameters e acesse a opção Create Parameter, conforme mostra a Figura 02
Ao acionar a opção Create Parameter, o Jaspersoft irá criar um novo parâmetro de nome “Parameter1”, conforme mostra a Figura 03.
Clique sobre o novo parâmetro e acesse a aba Properties, Figura 04. Algumas informações já virão preenchidas como Name e Class.
Agora mude o Name do parâmetro, para, por exemplo, tituloSeminario e pressione a tecla Enter. Na aba Outline ocorrerá uma mudança no nome do parâmetro, conforme mostra a Figura 05.
Parte 2 – Utilizando o parâmetro no relatório
Após a criação do parâmetro, é a hora de utilizá-lo no relatório. Como o relatório está em branco, adicionaremos um elemento novo na band Page Header do relatório, que irá se repetir em quantas páginas forem “impressas” pelo relatório. Assim se for impresso 4 páginas, nessas 4 haverá essa informação. O mesmo se aplica ao Page Footer, que irá repetir em todas as páginas os elementos que ali estiverem presentes. Para começar acesse a aba Palette e localize o elemento Text Field, conforme mostra a Figura 06.
Agora clique sobre o elemento Text Field e arraste-o para a área Page Header do relatório. Deverá aparecer um elemento dentro dessa área como mostra a Figura 07
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 08.
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 Parameters, localizada na primeira coluna, serão exibidos todos parâmetros existentes nesse relatório (segunda coluna), conforme mostra a Figura 09.
Desça até o fim da segunda coluna onde estará o parâmetro criado, tituloSeminario. De um duplo clique sobre este e ele aparecerá no padrão jasper na expressão, conforme mostra a Figura 10.
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ário 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 11.
1 |
"Seminário: " + $P{tituloSeminario} |
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 12.
A expressão criada ficou meio espremido. Para aumentar o tamanho clique e arraste um dos quadrados azuis do canto do elemento até o tamanho desejado, como mostra a Figura 13.
Por fim é bom ter em mente que o tamanho desse campo poderá variar muito, pois seu tamanho é dinâmico devido ao parâmetro existente. Aqui é uma boa prática na geração dos relatórios é 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 o parâmetro dentro do código 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 o novo parâmetro tituloSeminario e gerar o novo relatório criado via Jaspersoft Studio. Para tanto vamos criar uma instância de Map<String, Object> (linha 20), pois podemos passar parâmetros de qualquer tipo para o Jasper Reports, mas a Key deste sempre será uma String. Adicionaremos o novo parâmetro ao Map, com o “tituloSeminario” e uma String de exemplo “Seminário sobre Jasper Reports” (linha 21). Por fim esse Map será passado ao método fillReportToFile (linha 24), conforme demonstra o código 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 32 33 34 |
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(); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("tituloSeminario", "Seminário sobre Jasper Reports"); //Compilacao no formato jasper para o jrprint JasperFillManager.fillReportToFile("reports/relatorioTeste.jasper", parameters, 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 temos de modificar o nome do relatório, pois o relatorioTeste.jasper não corresponde ao relatório criado nesse artigo. O nome desse arquivo é alunosInscritosSeminario.jasper, assim nas linhas 24 e 31 devemos alterar o nome do arquivo, conforme mostra o código 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 32 33 34 |
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(); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("tituloSeminario", "Seminário sobre Jasper Reports"); //Compilacao no formato jasper para o jrprint JasperFillManager.fillReportToFile("reports/alunosInscritosSeminario.jasper", parameters, 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/alunosInscritosSeminario.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 o título passado pelo código Java, Seminário sobre Jasper Reports, no arquivo PDF.
finally{
Assim terminamos a descrição sobre como criar e enviar parâmetros 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!
Robson says
A parte onde voce coloca new JREmptyDataSource(1) siginifica que não tem um banco definido ? e se eu quiser definir um banco ?
Mauda says
Olá Robson, tudo bom?
Não é isso. A classe JREmptyDataSource apenas indica que não estarei passando nenhuma informação a mais como Field do relatório.
Se eu quiser passar uma informação que veio do banco de dados é recomendável você primeiro obter essa informação no Java e depois enviar ao relatório com a classe JRBeanCollectionDataSource; Veja a seguinte classe no link abaixo:
https://bitbucket.org/mauda/seminarioscientificos_2018_1/src/dbbe6fe70ddaf058358dbdebe334aba87d76666f/cientificos/src/test/java/br/com/mauda/seminario/cientificos/junit/tests/jasper/TesteAlunosInscritosSeminariosJasper.java?at=jasperReport&fileviewer=file-view-default
Repare que na linha 41 existe uma chamada a uma classe da camada de Business Controller que retorna uma lista de Alunos.
Agora veja a linha 51. É criado um objeto JRBeanCollectionDataSource que serve para inserir uma lista para ser trabalhada pelo jasper. Nessa criação do objeto eu passo a lista de Alunos.
Assim o relatório consegue obter essas informações.
Duvidas a disposição!
Obrigado.
Jessica Pergentino says
Olá Mauda, estou com uma duvida que está me matando. Tenho um projeto que tem q imprimir um relatório que contem duas listas e duas tabelas. Meu problema é o seguinte, estou sem intender como o jasper interpreta os dados que são passados pra ele, por causa do seguinte:
No meu relatório na primeira vez que eu fiz, no jasper studio eu criei o relatório com um banco fixo lá funcionava tudo perfeitamente, e ai eu passei esse relatório para o java, lá quando eu rodava o código o relatório era gerado com o banco que foi criado no jasper studio e não com os dados passado pelo java.
Então eu mudei o relatório e ai surgiram mais duvidas, por que eu mudei para a utilização de parâmetros assim como está no seu tutorial, mas o relatório aparece em branco, mesmo eu passando os parâmetros pelo java. A minha duvida é como o jasper interpreta esses dados que eu estou passando, tipo, no meu código eu passo a conexão do banco que eu estou usando, é mesmo necessário passa-la já que eu passo as informações por parâmetro?
Outra duvida, pesquisando na internet reparei que posso colocar parâmetros nas sqls dos dataset que crio no jasper studio, como que eu consigo passar esse parâmetros via java?
Mauda says
Olá Jessica, tudo bom?
Sua resposta dá um artigo inteiro :-), mas vou tentar deixar mais resumido. Para minha explicação me basearei nesse artigo:
http://mauda.com.br/?p=1420
O jasper trabalha com duas formas de passar informações. Parâmetros e Fields.
Quando estamos trabalhando com parâmetros, o Jasper entende diretamente o que passamos. Por exemplo, se passar a classe Casa e dentro do parâmetro estiver o tipo Casa, ele vai entender aquele parâmetro como casa.
Assim podemos fazer um $P{casa}.getEndereco(), que ele irá entender q estamos pegando o endereco.
O Field trabalha diferente, pois se eu passar esse mesmo casa, como field, não dá pra criar um field casa, mas sim vários fields com os atributos, por exemplo endereco.
Assim o mesmo exemplo acima com field seria um $F{endereco}, pois ele pega o nome do atributo diretamente.
Repare nas linhas de código abaixo
Map parameters = new HashMap ();
parameters.put(“tituloSeminario”, “Seminário sobre Jasper Reports”);
//Compilacao no formato jasper para o jrprint
JasperFillManager.fillReportToFile(“reports/alunosInscritosSeminario.jasper”, parameters, new JREmptyDataSource(1));
No método fillReportToFile, existem 3 parâmetros, um o nome do jasper, o segundo os parâmetros e o terceiro os Fields. Nesse caso um EmptyDataSource, mas poderiam ser outros DataSources próprios do Jasper.
Por fim, os fields são muitos utilizados em subrelatórios. Pois nós passamos o que queremos por parâmetro, por exemplo, um list e depois lá dentro do relatório chamamos um subrelatório passando essa lista como field desse subrelatório, assim o Jasper irá buscar os atributos e preencher esse subrelatório no formato de fields.
Não acho uma boa ideia fazer com banco fixo, pois depois vc terá que criar toda a lógica para enviar essa informação via Java. Vale mais a pena criar os métodos que recuperam essa informação do banco, assim você já tem correto o que o Java vai passar. Se o seu cliente fosse utilizar diretamente o Jasper para recuperar as informações, tudo bem, mas 99% dos casos não o é.
O Jasper é uma ferramenta muito, muito poderosa. Só tive q interromper a série de artigos por falta de tempo, mas tenho vários conhecimentos que gostaria de compartilhar. Quem sabe mais pra frente eu consiga.
Obrigado e duvidas a disposição.