Fazer download em docx, pdf ou txt
Fazer download em docx, pdf ou txt
Você está na página 1de 33

Tutorial: Tcnicas de Gerao de Relatrios com JasperReports Uma

abordagem utilizando a ferramenta de design iReport


Fortaleza CE, fevereiro de 2009 http://pablonobrega.wordpress.com

2. CONFIGURANDO O IREPORT
3. A APLICAO
3.1 O Banco de Dados
4. PREPARANDO OS RELATRIOS
4.1 Mtodo passando conexo com o banco de dados
4.1.1 Cdigo Java da Soluo
4.2 Mtodo passando ResultSet
4.2.1 Cdigo Java da Soluo
4.3 Mtodo passando Lista de Objetos
4.3.1 Cdigo Java da Soluo
5. TESTES DE DOCUMENTOS COM SUBRELATRIOS
6. CONFIGURAES TEIS
6.1 Configuraes de textFields
6.1.1 Campo deve ficar em branco quando for nulo
6.1.2 Valor do campo no aparece quando ultrapassa o limite de espao
6.1.3 Campo deve crescer de acordo com o valor a ser exibido
1. INTRODUO

4
7
8
9
9
18
18
20
20
36
37
40
40
40
41
41

Por diversas vezes tenho me deparado com pessoas tendo dificuldades para
gerar relatrios no JasperReports ou em utilizar os recursos do iReport - a
ferramenta de design para o JasperReports e isso me incentivou a criar esse
tutorial que mostra trs tcnicas para gerao desses documentos to
importantes em qualquer sistema: passando uma conexo com o banco,
passando um ResultSet (encapsulado na classe JRResultSetDataSource) e
passando uma lista de objetos de qualquer tipo (encapsulada na classe
JRBeanCollectionDataSource).

Duas outras caractersticas importantes desse tutorial so: o emprego de


subrelatrios - uma sada bastante til em vrios casos, sobretudo em
relatrios complexos, e a passagem de parmetros para o relatrio atravs de
um Map.
Para finalizar, disponibilizo o projeto do Eclipse no meu blog do WordPress
(http://pablonobrega.wordpress.com) a todos aqueles que desejam entender a
estrutura da aplicao finalizada. Na aplicao voc encontrar os arquivos
jrxml, os jasper, o script de criao do banco, etc.
Requisitos do Tutorial:
IReport 3.0 (http://jasperforge.org/plugins/project/project_home.php?
group_id=83); JasperReports 3.0 (includo o JAR no diretrio do IReport);
Eclipse Europa 3.3, ou algum outro IDE que aceite JSF
http://www.eclipse.org/europa/
Apache Tomcat 6.0, ou algum outro Servidor de Aplicao
(http://tomcat.apache.org/);
MySQL 5.0, ou algum outro SGBD (http://dev.mysql.com/downloads/);
2. CONFIGURANDO O IREPORT
Como toda boa ferramenta, o iReport precisa que sejam feitas algumas
configuraes aps a instalao na mquina. Abaixo dou o exemplo de
algumas que sempre uso para evitar a gerao de arquivos que no me
interessam e outras para que eu possa visualizar o resultado da gerao de
relatrios em PDF e em outros formatos (quando necessito).

Clique no item Opes do menu Opes.

Na aba Programas Externos, configure os programas que o iReport utilizar


para abrir os arquivos gerados em outros formatos (para efeito de testes
internos). No exemplo acima, est configurado o Adobe Acrobat Reader para
abrir arquivos PDF.

Na aba Cpia, marque a opo Sem backup para evitar que o iReport gere
arquivos bak sempre que voc efetua alteraes no relatrio.

Na aba Compilador, marque a opo Usar o diretrio do relatrio para os


compilados. Isso far com que o iReport gere o arquivo jasper no mesmo local
onde est o jrxml. Alm disso, desmarque a opo manter arquivo .java (se
disponvel).
3. A APLICAO

O objetivo da aplicao muito simples: gerar relatrio dos alunos cadastrados


no banco e seus respectivos professores. Alguns mtodos so utilizados pelos
trs modelos de gerao dos relatrios. So eles:
Mtodo que retorna o caminho completo de um arquivo ou pasta da aplicao.
Mtodo para retornar o nome da aplicao.
Mtodo que gera o arquivo PDF.
Mtodo que cria a conexo com o banco de dados (chamado no construtor da
classe).
Mtodo que retorna a conexo aberta.
public Connection getConexao() { return conexao; public void criaConexao()
throws ClassNotFoundException, SQLException {
String endereco = "localhost"; String porta = "3306"; String banco =
"academico"; String usuario = "root"; String senha = ""; try {
Class.forName("com.mysql.jdbc.Driver"); conexao =
DriverManager.getConnection("jdbc:mysql://" + endereco + ":" + porta + "/" +
banco + "?user=" + usuario
} catch (ClassNotFoundException ex) { throw ex; } catch (SQLException ex)
{ throw ex; private String getDiretorioReal(String diretorio) {
HttpSession session = (HttpSession)
FacesContext.getCurrentInstance().getExternalContext().getSession(false);
return session.getServletContext().getRealPath(diretorio); } private String
getContextPath() {
HttpSession session = (HttpSession)
FacesContext.getCurrentInstance().getExternalContext().getSession(false);
return session.getServletContext().getContextPath(); } private void
preenchePdf(JasperPrint print) throws JRException {
// Pego o caminho completo do PDF desde a raiz saida =
getDiretorioReal("/pdf/relatorio.pdf"); // Exporto para PDF
JasperExportManager.exportReportToPdfFile(print, saida); /* * Jogo na varivel
sada o nome da aplicao mais o

* caminho para o PDF. Essa varivel ser utilizada pela view


*/ saida = getContextPath() + "/pdf/relatorio.pdf"; }
A pgina JSF que exibir os relatrios tem o seguinte cdigo:
Observe que se a varivel sada estiver vazia, uma mensagem de erro ser
exibida. Do contrrio, ser exibido o iFrame. Utilizei essa tcnica para evitar
que a tela fique em branco quando o relatrio no foi gerado por algum motivo.
3.1 O Banco de Dados
Utilizo o SGBD MySQL 5.0 para efetuar as demonstraes. O nome do banco
acadmico e o Diagrama Relacional ficou da seguinte forma:

Dica: se sua fonte de dados ficar no MySQL, utilize o MySQL Workbench


(sucessor do
DBDesigner) para criar seu Diagrama Relacional. Foi com ele que gerei o
modelo acima e o script de criao do banco e a vantagem que o software
totalmente gratuito. Segue link para download:
http://dev.mysql.com/downloads/workbench/5.1.html
<h:outputText rendered="#{empty relatorioBean.saida}" value="Relatrio no
gerado. Consulte o Administrador do Sistema." /> <f:subview id="relatorio"
rendered="#{not empty relatorioBean.saida}"> <iframe id="iframe"
src="#{relatorioBean.saida}" width="9%" height="600px" style="min-height:
400px;"> </iframe>
4. PREPARANDO OS RELATRIOS

Para fins de praticidade, utilizarei o Assistente de Relatrio do prprio iReport


para gerar o layout do relatrio e algumas pequenas modificaes visuais
sero feitas para que as informaes fiquem melhor distribudas. claro que,
medida que eu faa essas alteraes, chamarei a ateno do leitor para o
layout que existia antes, como ficou e porque efetuei as mudanas.
4.1 Mtodo passando conexo com o banco de dados
Nesse primeiro exemplo, vamos preparar um relatrio que receber uma
conexo com o banco de dados aberta pela nossa aplicao Java para gerar
um PDF.

Selecione a opo Assistente de relatrio.


Como iremos passar uma conexo com o banco de dados para o relatrio,
vamos ter que configurar qual a query a ser executada pelo banco, o banco de
dados, o schema (no caso de alguns SGBDs), etc. Clique em Novo, na opo
Conexes / Fonte de Dados para configurar.
Selecione a opo Conexo de Banco de Dados JDBC.
Vamos agora configurar os parmetros da conexo, como o driver JDBC, a
URL de conexo, usurio, senha e o banco a serem utilizados. Obs.: para
alguns SGBDs (como o Postgres), ser preciso colocar o jar do banco na
pasta lib do iReport. Clique em Salvar.

Clique agora em Design query para modelarmos graficamente a consulta a ser


executada.

Do lado esquerdo selecionamos as tabelas a serem utilizadas. Depois, em


cada tabela, selecionamos os campos a serem exibidos ou necessrios ao
relatrio. Por ltimo - sendo esse o caso - podemos modificar o tipo de JOIN
que ser realizado entre as tabelas clicando duas vezes nos quadradinhos
vermelhos.

A consulta agora aparece no campo reservado a ela. Clique em Prximo para


continuar.

Nessa tela, vamos selecionar os campos da consulta que iro aparecer no


relatrio. Nesse caso passe todos para o select da direita.
Nossa query vai retornar, em cada linha do resultado da consulta, o nome e a
matrcula do aluno, o nome do professor, etc. lgico que no interessa para o
usurio ver dados de cada aluno repetidos diversas vezes em toda exibio de
um professor dele. Para que o aluno seja mostrado somente uma vez e logo
em seguida todos os seus professores, precisamos de um agrupamento pelo id
do aluno. Faa a configurao conforme a figura acima e clique em Prximo.
Escolhe o layout do relatrio. Na seleo acima (colunar) cada dado fica abaixo
do outro com seu label do lado esquerdo, como veremos logo mais.
Pronto. Processo concludo. Agora precisamos somente clicar em Encerrar e
fazer alguns ajustes.

Esse o resultado. A rea com o retngulo vermelho mostra onde est o


agrupamento (o iReport cria uma banda para ele). Isso significa que, para cada
aluno, ser exibido o seu id e logo abaixo cada um dos seus professores,
juntamente com o nome e a matrcula do aluno (isso para cada professor, o
que representa uma repetio desnecessria de dados).

Para corrigir esse problema e tambm no mostrar o id do aluno, aumentei a


banda do agrupamento (rea marcada com fundo preto) e coloquei l a
matrcula e o nome do aluno, alm de apagar o label e o textField com o id do
aluno.

Vamos agora Compilar nosso relatrio para gerar o arquivo jasper a ser
utilizado pela nossa aplicao. Selecione a opo mostrada acima. Obs.: para
acompanhar o andamento, erros e outros detalhes, consulte as abas
Processos e Console de Sada (marcadas com o crculo vermelho).

Como eu no havia salvo o arquivo, o iReport pede para que voc d um nome
para o arquivo e selecione seu local. Para aplicaes web interessante usar
nomes sem espao.

Vamos agora executar o relatrio para ver o resultado final. O iReport vai
conectar no banco, extrair as informaes e gerar o resultado. O relatrio ser
mostrado no JRViewer (conforma seleo acima marcao em vermelho).
Para gerar em outros formatos, selecione outra opo de visualizao.

O resultado da gerao esse acima. Agora precisamos colocar o arquivo


jasper gerado na nossa aplicao e prepar-la para usar esse arquivo.
4.1.1 Cdigo Java da Soluo
Ao processarmos o mtodo geraRelatorioPassandoConexao() do nosso
Managed Bean, ser gerado o relatrio em PDF e ento a navigation rule
exibeRelatorio ser chamada.
4.2 Mtodo passando ResultSet
Para efeitos de praticidade, vamos utilizar o mesmo relatrio anterior, pois no
precisamos fazer nenhuma mudana na configurao de um documento
quando passamos a utilizar o ResultSet.
Nesse tipo de abordagem, efetuamos a query no banco a partir da nossa
prpria aplicao e enviamos para o JasperReports o ResultSet gerado
encapsulado na classe JRResultSetDataSource. O nico detalhe com o qual
devemos nos preocupar o fato de os nomes das colunas do ResultSet
precisarem ser idnticos aos textFields do relatrio. Para exemplificar, no nosso
caso, para o id do aluno, por exemplo, devemos usar o nome da coluna
aluno_id_aluno e para o nome do professor o nome da coluna deve ser
professor_nome (veja figura abaixo), pois os nomes dos textFields no iReport
devem ser iguais aos alias gerados pela consulta ao banco.
public String geraRelatorioPassandoConexao() { saida = null;

String jasper = getDiretorioReal("/jasper/professores_por_aluno.jasper");


Connection conexao = null; try {
// Abro a conexo com o banco que ser passada para o JasperReports
conexao = new Conexao().getConexao();
// Mando o jasper gerar o relatrio JasperPrint print =
JasperFillManager.fillReport(jasper, null, conexao);
// Gero o PDF preenchePdf(print); // VEJA O MTODO NO CAPTULO 3 DO
TUTORIAL
} catch (Exception e) { e.printStackTrace(); } finally { try {
// Sempre mando fechar a conexo, mesmo que tenha dado erro if (conexao !=
null) conexao.close(); } catch (SQLException e) { return "exibeRelatorio"; }

Trecho da query configurada no iReport (marcado na cor vermelha). Trecho da


query configurada no iReport (marcado na cor vermelha).
4.2.1 Cdigo Java da Soluo
Observe que o ResultSet deve estar encapsulado pela classe
JRResultSetDataSource.
Mtodo que retorna o ResultSet da query executada no banco.

4.3 Mtodo passando Lista de Objetos


Esse o mtodo mais interessante de gerao de relatrios. Ele pode ser
utilizado como uma alternativa aos dois outros mtodos ou quando o relatrio
muito complexo.
Para facilitar, novamente aproveitei o modelo anterior existente, fazendo
apenas algumas pequenas alteraes. No se esquea de salvar o novo
relatrio com outro nome. Coloquei ainda um subrelatrio que bastante til
em situaes complexas ou especficas. O legal dessa soluo que o
relatrio principal vai receber uma lista de objetos e o subrelatrio uma
conexo com o banco.
private ResultSet getResultSet(Connection conexao) throws SQLException,
ClassNotFoundException {
Statement stmt = conexao.createStatement(); ResultSet rs =
stmt.executeQuery("SELECT aluno.nome AS aluno_nome, " + "aluno.matricula
AS aluno_matricula, professor.nome AS professor_nome, " + "aluno.id_aluno
AS aluno_id_aluno FROM aluno aluno " + "INNER JOIN professores_alunos
professores_alunos ON aluno.id_aluno = " + "professores_alunos.id_aluno
INNER JOIN professor professor ON " + "professores_alunos.id_professor =
professor.id_professor"); return rs; } public String
geraRelatorioPassandoResultSet() { saida = null;
String jasper = getDiretorioReal("/jasper/professores_por_aluno.jasper");
Connection conexao = null; try {
// Abro a conexo com o banco conexao = new Conexao().getConexao();
// Gero o ResultSet que ser enviado a partir da conexo aberta
JRResultSetDataSource jrsds = new
JRResultSetDataSource(getResultSet(conexao));
// Mando o jasper gerar o relatrio JasperPrint print =
JasperFillManager.fillReport(jasper, null, jrsds);
// Gero o PDF preenchePdf(print); } catch (Exception e) { e.printStackTrace(); }
finally { try {
// Sempre mando fechar a conexo, mesmo que tenha dado erro if (conexao !=
null) conexao.close(); } catch (SQLException e) {

} return "exibeRelatorio"; }

Esse relatrio no ter agrupamento de dados - vamos utilizar um subrelatrio


para os professores -, portanto, antes de excluirmos o agrupamento, vamos
mover todos os campos para a banda detail (marcada na cor vermelha). Isso
necessrio para que esses campos no sejam perdidos.

Vamos agora tirar o agrupamento do relatrio. Entre na opo Agrupamentos


do Relatrio do menu Visualizar.

Selecione aluno_id_aluno e clique em Excluir. Pronto. O relatrio deve ficar


com a aparncia acima, j sem a banda de agrupamento por id do aluno.

Como no teremos dados sobre os professores dos alunos nesse relatrio


isso ser tarefa do subrelatrio -, precisamos mudar a query do banco. Entre
em Query do Relatrio no menu Data. Essa query ser modificada e
configurada apenas para efeito de testes, j que iremos passar uma lista de
objetos para o relatrio e a query no ser executada.
Apague toda a query para podermos refazer tudo novamente (o Query
Designer tem um bug se quisermos tirar algumas tabelas ou colunas da query
anterior). Clique em Query Designer.

Selecione apenas a tabela aluno, marque todos os campos e clique em OK.


Podem observar que a idia que esse relatrio seja mais detalhado.

A query do relatrio ficar como a mostrada acima.

Precisamos que os textFields do nosso relatrio batam com os nomes dos


atributos da classe que estar na lista do relatrio. Na classe Aluno da minha
aplicao, tenho os seguintes atributos: nome, matricula, situacaoFrequencia e
situacaoPagamento. Precisamos renomear os alias das colunas (marcados na
cor vermelha) para os nomes acima.

Precisamos agora atualizar os textFields colocando o valor correto para o que


contm aluno_matrcula (ser agora $F{matricula}) e para o que contm
aluno_nome (ser agora $F{nome}). Vamos tambm inserir os labels
freqncia e pagamento e inserir os textFields correpondentes com os valores
$F{situacaoFrequencia} e $F{situacaoPagamento}}. Para facilitar basta arrastar
da estrutura, onde tem o ns Campos (lado esquerdo, inferior da tela) para o
relatrio.

(Parte 2 de 2)

Precisamos excluir tambm os campos relacionados ao professor. Ao final de


tudo o relatrio ficar como est a imagem acima. Vamos agora adicionar o
subrelatrio. Clique no cone marcado em vermelho na imagem acima para
fazer essa operao.

Crie uma rea logo abaixo dos campos com o fundo preto (matrcula,
freqncia, etc), de preferncia utilizando a largura do relatrio por inteiro. A
tela acima mostrada. Deixe a conexo como est e entre com a query a ser
executada pelo subrelatrio. No exemplo acima coloquei a id do aluno com o
valor 1 apenas para o iReport deixar eu passar dessa tela. Clique em Prximo.

Marque os campos que deseja que o iReport exiba. No nosso caso, vamos
selecionar todos. Clique em Finalizar.

Selecione o layout do relatrio. Decidi que o relatrio funcionar com um


cabealho superior e os valores abaixo (uma linha para cada professor do
aluno), ento selecionei o layout tabular.

Esse passo muito importante. Nele vamos indicar o nome do subrelatrio e


como ser referenciado pelo relatrio principal. Como nosso relatrio e o
subrelatrio podem mudar seus caminhos vamos dizer para o iReport que o
caminho para o subrelatrio ser passado atravs de um parmetro chamado
SUBREPORT_DIR.

O subrelatrio deve ter uma aparncia semelhante a que se encontra na


imagem acima. Fiz apenas alguma modificaes nas larguras dos textFields.
Observem como est a query do relatrio. Logo mais, o nmero 1 ser
modificado por um parmetro.

Voltando ao relatrio principal, vamos agora modificar algumas configuraes


do subrelatrio. Clique duas vezes em cima dele.

Na aba Sub-Relatrio (Outro) podemos observar que o iReport se encarregou


de configurar o caminho para o subrelatrio concatenando o seu nome com o
diretrio passado por parmetro ($P{SUBREPORT_DIR}). Vamos agora passar
um parmetro do relatrio principal para o subrelatrio que servir para fazer a
query listando os professores de um determinado aluno. Clique no boto
Adicionar.

Na janela a seguir, digite idAluno no Nome de Parmetro do Sub-Relatrio.


Depois clique no boto do lado direito (marcado na cor vermelha).
Na expresso, digite $F{idAluno}. Clique em Aplicar.

Com essa configurao, estamos dizendo para o JasperReports que para cada
aluno colocado na tela, ele vai gerar um subrelatrio que receber como
parmetro o id do aluno que foi processado. Clique em OK.

A tela deve ficar como a que est acima.

Na aba Subrelatrio, mude a Expresso de Conexo/Fonte de Dados de


$P{subConnection} para $P{REPORT_CONNECTION}. Com isso voc est
dizendo para o JasperReports que a conexo com o banco de dados utilizada
pelo subrelatrio, est na chave REPORT_CONNECTION da lista de
parmetros.

Voltando para o subrelatrio, vamos agora mudar a Query do Relatrio para


poder receber o parmetro passado e mostrar somente os professores do
aluno correto. Entre novamente na opo Query do Relatrio do menu Data.
Mude o valor 1 que tinha antes para $P{idAluno}, o parmetro que est vindo
do relatrio principal. Clique em OK.

Vamos agora preparar o subrelatrio para receber o parmetro do relatrio


principal. Entre na opo Parmetros do Relatrio, no menu Visualizar.

Na aba Parmetros, clique no boto Novo.

Coloque o nome do parmetro idAluno e informe que do tipo Integer. Clique


em OK. Salve os dois relatrios e mande compilar.
4.3.1 Cdigo Java da Soluo
Observe que no caso de passarmos uma lista, devemos encapsul-la na classe
JRBeanCollectionDataSource.

private ArrayList<Aluno> getListaAlunos(Connection conexao) throws


SQLException { return (ArrayList<Aluno>) new AlunoDao().loadAll(conexao); }
public String geraRelatorioPassandoListaDeObjetos() { saida = null; String
jasper = getDiretorioReal("/jasper/professores_por_aluno_com_lista.jasper");
Connection conexao = null; try {
// Conexo com o banco para o segundo relatrio conexao = new
Conexao().getConexao();
// criao dos parametros Map<String, Object> map = new HashMap<String,
Object>();
// conexo com o banco que ser utilizada pelo subrelatrio
map.put("REPORT_CONNECTION", conexao); // pego o caminho do diretrio
onde se encontra o subrelatrio map.put("SUBREPORT_DIR",
getDiretorioReal("/jasper/") + "/"); ArrayList<Aluno> alunos =
getListaAlunos(conexao);
JRBeanCollectionDataSource ds = new
JRBeanCollectionDataSource(alunos); /* * Mando o jasper gerar o relatrio.
Nesse caso passo o map,
* j que ele tem dois parmetros que sero utilizados
JasperPrint print = JasperFillManager.fillReport(jasper, map, ds); // Gero o PDF
preenchePdf(print); } catch (Exception e) { e.printStackTrace(); } return
"exibeRelatorio"; }
5. TESTES DE DOCUMENTOS COM SUBRELATRIOS
Um grande problema com o qual me deparei quando comecei a usar o iReport
foi o de realizar testes quando o relatrio principal possua uma subrelatrio.
Isso porque o subrelatrio referenciado pelo JasperReports atravs do
parmetro SUBREPORT_DIR e quando mandamos executar o relatrio
principal - caso voc no efetue a configurao a seguir - o subrelatrio no
encontrado. Para contornar isso, realizaremos uma configurao adicional,
conforme as telas a seguir (o exemplo abaixo se aplica no exemplo de relatrio
com listas explicado no subcaptulo 4.3):

Entre nos parmetros do relatrio principal, escolha SUBREPORT_DIR e clique


em Modificar.

Em Valor Padro da Expresso, coloque o caminho para o diretrio onde se


encontra o arquivo jrxml do subrelatrio. Agora clique em Executar relatrio
(usar conexo ativa).

A tela a seguir ser exibida. Clique em Usar padro.

Pronto! O relatrio principal foi gerado executando a consulta no banco e o


subrelatrio funcionou com a mesma conexo utilizada pelo relatrio principal.
Observe que cada aluno tem sua lista de professores.
6. CONFIGURAES TEIS 6.1 Configuraes de textFields
As configuraes a seguir se aplicam quando se faz a operao a seguir:

Clique com o boto direito sobre o textField e escolha a opo Propriedades


6.1.1 Campo deve ficar em branco quando for nulo

Marque a opo Em branco quando for nulo da aba Campo texto.


6.1.2 Valor do campo no aparece quando ultrapassa o limite de espao

Marque a opo Imprimir quando detalhes excederem na aba Comum. 6.1.3


Campo deve crescer de acordo com o valor a ser exibido

Marque a opo Aumentar quando exceder na aba Campo texto.


6.1.4 Campo deve ser exibido com formatao HTML Marque a opo HTML
no item Markup da aba Fonte.

Você também pode gostar