Você está na página 1de 164

C:\Users\LucilioRocha\Documents\NetBeansProjects\GesTenis\relatorios\reportFornecedor.

jr
xml
http://davidbuzatto.com.br/2010/10/10/jasperreports-trabalhando-com-relatorios-em-javaparte-2-primeiros-relatorios/

JasperReports: Trabalhando com Relatrios em Java


Parte 1 (Configurando o Ambiente)
Filed under: Desktop, Java, Programao, Relatrios 38 Comentrios
09/10/2010

28 Votes
Parte 1 Parte 2 Parte 3 Parte 4 Parte 5
Ol a todos. Quem acompanha o blog sabe que no ltimo post h duas semanas atrs
eu pedi que vocs sugerissem o tema para o prximo tutorial. Dentre os temas que eu
listei, o de criao de relatrios em Java foi o que ganhou. Este tutorial, como o de Flex
e Java, vai ser dividido em algumas partes. Eu poderia escrever em apenas um post tudo
sobre o tema, mas preferi dividir o tutorial em vrias partes pequenas menores que os
tutoriais sobre Flex para no ficar muito cansativo.
Nesta primeira parte (provavelmente a maior de todas), iremos aprender sobre o
framework para criao relatrios que iremos utilizar, o JasperReports, entendendo seu
funcionamento, aprendendo a obter e instalar o iReport, que o editor de relatrios e
preparar nosso ambiente de desenvolvimento. Irei novamente utilizar o NetBeans como
IDE de desenvolvimento, mas voc que usa o Eclipse ou qualquer outra IDE Java no
vai ter dificuldades para seguir o tutorial.
Na segunda parte, iremos criar uma base de dados de teste para popularmos nossos
relatrios e vamos aprender como criar, compilar e utilizar os relatrios criados em
aplicaes desktop. Na terceira parte, iremos aprender a criar subrelatrios. Na quarta,
iremos utilizar fontes de dados data sources diferentes, permitindo ento que
possamos listar dados nos relatrios que no vem somente de consultas SQL. Por fim,
na quinta e ltima parte, iremos aprender como utilizar nossos relatrios em uma pgina
Web. Aps todas essas partes, vocs tero a bagagem necessria para caminharem
sozinhos ;)
Ento, vamos comear!

Existem atualmente na indstria diferentes frameworks e engines para criao e


processamento de relatrios. Dentre as solues pagas, talvez o Crystal Reports seja a
mais conhecida. O Crystal Reports uma soluo robusta e que pode ser utilizada com
diversas linguagens de programao. Outra soluo paga que muito utilizada por
quem trabalha com Delphi o Quick Reports. Em Java, existem atualmente duas
solues que so mais utilizadas. O JasperReports, que o framework gratuito mais
popular e que iremos utilizar nos nossos tutoriais e o BIRT (Business Intelligence and
Reporting Tools) que tambm gratuito e mais utilizado por quem trabalha com o
Eclipse.
Como iremos utilizar o JasperReports, vale a pena ento entendermos um pouco do seu
funcionamento. Quando trabalhamos com ele, ns criamos os arquivos de cdigo fonte
dos nossos relatrios utilizando XML, sendo que esse arquivo fonte de extenso
.jrxml passa por um processo de compilao para gerar gerar arquivos .jasper, que por
sua vez so interpretados pela engine do JasperReports. Ns no iremos escrever esses
arquivos .jrxml na mo, pois iremos construir nossos relatrios utilizando um editor
WYSIWYG (What You See Is What You Get), o iReport. Atualmente, o iReport pode
ser obtido em duas verses. Uma delas standalone (criada usando a NetBeans
Platform), no precisando de nenhum outro programa para ser utilizada, enquanto a
outra um plugin para o NetBeans. Iremos utilizar a verso em plugin.
Bem, j falei demais. Chega de blablabl, vamos comear a por a mo na massa, afinal
essa a melhor forma de aprender :D. Primeiro vamos baixar o iReport. Acesse ento o
endereo http://jasperforge.org/projects/ireport e procure o link de download. Na verso
atual do site, para fazer o download, basta clicar no boto Download iReport Now. Ao
clicar no boto, sero apresentadas as verses disponveis. Ns vamos escolher a ltima:
Plugin for NetBeans IDE 3.x. A verso atual do iReport a 3.7.5. Note que a verso do
iReport sempre vai ser a mesma do JasperReports.
Quando terminar de baixar, descompacte o arquivo iReport-3.7.5-plugin.zip (a verso
pode variar dependendo de quando voc baixar o pacote). Sero extrados 4 arquivos
com a extenso .nbm (NetBeans Module). Esses arquivos so os pacotes dos plugins que
sero instalados no NetBeans. Com o arquivo descompactado, abra ento o seu
NetBeans. Estou usando a tlima verso, 6.9.1. Com o NetBeans aberto, v no menu
Tools (Ferramentas) e escolha Plugins. Ao abrir o gerenciador de plugins, v na aba
Downloaded (Baixados?). nessa aba que voc instala os arquivos .nbm. Clique em
Add Plugins (Adicionar Plugins). Veja a Figura abaixo:

Gerenciador de Plugins
Ao clicar no boto Add Plugins, um dilogo ser aberto. Neste dilogo, procure ento
pelos arquivos .nbm que foram descompactados a partir do pacote que fizemos
download. Assim que os encontrar, selecione todos e clique Open (Abrir). Veja a Figura
abaixo.

Escolhendo os pacotes
Ao fazer isso, a janela do gerenciador de plugins ser exibida novamente, s que agora
com os quatro pacotes sendo exibidos. Deixe os quatro pacotes marcados e clique em
Install (Instalar). Veja a Figura abaixo.

Gerenciador de Plugins (instalao)


No primeiro passo do instalador, clique em Next (Prximo). Marque o checkbox para
concordar com os termos da instalao e clique em Install. Aguarde o final da
instalao. Quando a instalao terminar, provavelmente o NetBeans vai pedir para ser
reiniciado. Reinicie a IDE. Quando o ambiente estiver aberto novamente, voc vai
perceber que na barra de ferramentas foi inserido um novo boto e um combobox. Ainda
no iremos aprender para que eles servem, por enquanto entenda que eles fazem parte
do plugin do iReport. Veja a Figura abaixo.

Barra de ferramentas alterada


Com o iReport instalado, vamos agora preparar a estrutura de uma aplicao que iremos
usar nas prximas partes do tutorial. Inicie a criao de um novo projeto no NetBeans
escolhendo um projeto do tipo Java Application (Aplicao Java). Veja a Figura abaixo.

Novo projeto
Clique em Next. Em seguida, d o nome ao projeto, sugiro TutorialRelatorios (sem as
aspas), escolha onde o projeto vai ser salvo e marque a opo Use Dedicated Folder for
Storing Libraries (essa opo vai fazer com que todos os arquivos .jar utilizados fiquem
contidos dentro do projeto, sob o diretrio lib), configure as outras opes de acordo
com a Figura abaixo e clique em Finish.

Configurando o novo projeto


Ao clicar em Finish, o projeto vai ser criado. A partir de agora j poramos comear a
criar nossos relatrios no iReport, mas ainda faltam algumas configuraes para que
possamos fazer esses relatrios executarem dentro de uma aplicao. Para isso, ainda
temos que adicionar o JasperReports no nosso projeto, bem como todas as suas
dependncias, alm de termos tambm que organizar a estrutura do projeto para guardar
nossos relatrios.
Primeiro vamos tratar dos .jars. Ao instalar os plugins do pacote do iReport, uma
biblioteca padro com os .jars criada, mas ela vem com alguns erros, ento vamos
criar a nossa biblioteca para no termos dores de cabea depois. Para isso, expanda o n
raiz do projeto e procure pelo n Libraries (Bibliotecas). Clique com o boto direito e
escolha Add Library (Adicionar Biblioteca). Veja a Figura abaixo.

Nova biblioteca
Ao clicar em Add Library, o dilogo para a insero de bibliotecas ser exibido. Neste
dilogo, clique no boto Create (Criar). Veja a Figura abaixo.

Criando uma nova biblioteca


Ao clicar em Create, ser exibido um novo dilogo, onde o nome e o tipo da nova
biblioteca devem ser definidos. Em Library Name (Nome da Biblioteca), configure

como JasperReports-3.7.5, lembrando de mudar o nmero da verso caso esteja


utilizando uma verso mais nova. Em Library Type (Tipo da Biblioteca), deixe como
Class Libraries (Bibliotecas de Classe). Por fim, clique no boto OK. Veja a Figura
abaixo.

Criando uma nova biblioteca


Ao clicar em OK, ser exibido o dilogo Customize Library (Personalizar Biblioteca?).
nele que indicaremos os .jars que fazem parte da nossa biblioteca. Quando instalamos
o plugin do iReport no NetBeans criada uma pasta chamada ireport dentro do
diretrio de instalao e l que esto os .jars que precisamos. Sabendo disso, clique
ento no boto Add JAR/Folder (Adicionar JAR/Diretrio). Veja a Figura abaixo.

Adicionando os JARs
Com o dilogo aberto, procure pelo diretrio onde a instalao do NetBeans foi feita.
No meu caso, ele foi instalado em C:\Program Files (x86)\NetBeans 6.9.1\. Dentro deste
diretrio, procure pelo diretrio chamado ireport e entre nele. O contedo do diretrio
exibido na Figura abaixo, sendo que os diretrios que nos interessam so o diretrio
libs e o diretrio modules destacados na Figura.

libs e modules
Primeiramente, acesse o diretrio libs. Dentro dele, existe apenas um .jar (para a
verso 3.7.5 do iReports). Selecione esse .jar (xalan.jar) e clique em Add JAR/Folder.
Veja a Figura abaixo.

Adicionando xalan.jar
Ao clicar, o NetBeans vai perguntar se voc deseja mesmo criar um diretrio dentro do
diretrio libs (aquele que vai guardar nossas bibliotecas) com o nome de

JasperReports-3.7.5 (o nome que demos para a biblioteca, lebram?). Responda Sim.


Veja a Figura abaixo.

Alerta de criao de novo diretrio


Ao aceitar a criao do novo diretrio, a janela Customize Libraries voltar a aparecer,
agora com o xalan.jar sendo mostrado na lista de .jars. Alm da pasta libs, precisamos
adicionar tambm os .jars que esto dentro da pasta modules. Ento clique novamente
no boto Add JAR/Folder da janela Customize Libraries e entre no diretrio modules.
Dentro dele existiro alguns .jars, mas no so eles que queremos. Note que alm dos
.jars, existe um diretrio chamado ext. Entre nele. Neste diretrio esto TODAS as
dependncias do JasperReports. Para facilitar as coisas, iremos selecionar TODOS os
.jars. Em um projeto real, o mais sensato seria selecionar apenas os .jars que voc tem
certeza que vo ser utilizados. Entretanto, esta abordagem traz um problema. O Jasper
utiliza nos bastidores muitos desses .jars, mesmo que a gente pense que no. Um
exemplo o spring.jar :(. E o pior! A cada verso, as dependncias mudam (j tive
vrios problemas com isso). Minha recomendao que voc selecione TODOS os
.jars, e depois, caso j utilize um deles (por exemplo o Hibernate) recomendo ento que
voc atualize o .jar para a verso mais nova. Enfim, selecione TODOS e clique em Add
JAR/Folder. Veja a Figura abaixo.

Jars do diretrio modules/ext


Ao fazer isso, novamente a janela Customize Library vai ser exibida, mostrando que
todos os .jars foram inseridos. Clique em OK. Ao clicar, o dilogo Add Library ser
exibido novamente, mas agora com a nova biblioteca criada. Selecione-a (j vai estar
selecionada por padro) e clique em Add Library. Veja a Figura abaixo.

Adicionando a biblioteca no projeto


Fazendo isso, o dilogo ser fechado e voc vai perceber que todos os .jars aparecero
dentro do projeto. Veja a Figura abaixo.

Projeto com a biblioteca adicionada


Ok, j temos a biblioteca configurada com todos os .jars do JasperReports. Agora
vamos criar um diretrio no nosso projeto para conter as definies dos nossos
relatrios (arquivos .jrxml). Para isso, clique com o boto direito no n raiz do projeto e
escolha Properties (Propriedades). Veja a Figura abaixo.

Acessando as propriedades do projeto


Ao clicar em Properties, a janela de propriedades do projeto ser exibida. Nesta janela,
selecione o primeiro n esquerda (Source Fonte) e do lado direito, na tabela Source
Package Folders, clique em Add Folder (Adicionar Diretrio). Veja a Figura abaixo.

Propriedades do projeto
Ao clicar em Add Folder, um dilogo ser exibido. Neste dilogo, clique no boto
localizado no canto superior direito. Veja a Figura abaixo.

Boto para criar um novo diretrio


Com isso, um novo diretrio ser criado. D o nome de relatorios (sem as aspas e sem
acento agudo), selecione-o e clique em Open. Veja a Figura abaixo.

Diretrio "relatorios" criado


Ao clicar em Open, o novo diretrio ser inserido na tabela Source Package Folders. Na
primeira coluna apresentado o caminho do diretrio, enquanto na segunda coluna
apresentado o label que vai identificar esse diretrio dentro do projeto. Clique duas
vezes na clula da segunda coluna que corresponde ao label do diretrio criado e d o
nome de Relatrios. Cuidado! Ao terminar de editar o nome, tecle <ENTER>. Veja a
Figura abaixo.

Configurando o novo diretrio


Ao fazer isso, o label ser configurado (saindo da edio) e voc agora deve clicar no
boto OK das propriedades do projeto, aceitando assim as modificaes que foram
feitas. Veja a Figura abaixo.

Aceitando as configuraes
Pronto, terminamos a configurao do projeto. Se tudo tiver dado certo, o novo diretrio
ser exibido na estrutura do projeto, sendo que ele ser identificado pelo label que foi
configurado no passo anterior. Veja a Figura abaixo.

C:\Program Files\IreportPlugins

Estrutura do projeto atualizada


Com isso terminamos a primeira parte do tutorial. Aprendemos alguns conceitos sobre o
JasperReports e como instalar o iReport. Aprendemos tambm a criar e a inserir uma
nova biblioteca no projeto, sendo que essa biblioteca corresponde aos .jars necessrios
para ns utilizarmos o JasperReports no nosso programa (quando formos abrir o
relatrio a partir do programa). Alm disso, aprendemos a criar um diretrio dedicado
aos nossos relatrios. Ento isso. Terminamos a primeira parte do tutorial. Com o
cenrio pronto, agora podemos comear a brincar com o iReport e criar nossos
primeiros relatrios.
O projeto completo at o momento pode ser obtido neste link.
Fiquem ligados, a prxima parte vem ai ;)
Parte 1 Parte 2 Parte 3 Parte 4 Parte 5

JasperReports: Trabalhando com Relatrios em Java


Parte 2 (Primeiros Relatrios)

Filed under: Desktop, Java, Programao, Relatrios 53 Comentrios


10/10/2010

22 Votes
Parte 1 Parte 2 Parte 3 Parte 4 Parte 5
Ol! Nesta segunda parte do tutorial sobre criao de relatrios, vamos fazer nossos
primeiros exemplos, entretanto, para que possamos ver algum resultado, ou seja, nossos
relatrios preenchidos com valores, precisamos de uma base de dados para extrairmos
tais dados. Ao invs de criar uma base de dados na mo, iremos utilizar uma base j
pronta. Nos nossos exemplos, vamos utilizar o MySQL como SGBD e iremos utilizar
tambm o Sakila Sample Database para extrairmos nossos dados. Essa base de dados,
uma base de exemplo que disponibilizada no site no MySQL
(http://dev.mysql.com/doc/sakila/en/sakila.html),
que
pode
ser
usada
por
desenvolvedores para fazer testes com consultas SQL. Como nossos primeiros relatrios
vo trabalhar exclusivamente com SQL, vamos utilizar essa base de dados para facilitar
nossa vida.
Ento, mos a obra! Primeiramente, acesse http://dev.mysql.com/doc/index-other.html e
procure por Sample Databases. Nesta seo, so apresentadas algumas bases de dados
de exemplo que podemos baixar. Procure pela sakila database e baixe a base de dados
escolhendo o formato desejado (TGZ ou Zip) na primeira coluna. Para facilitar, este link
o link para baixar a verso em Zip.
Quando terminar de baixar o arquivo, descompacte-o. Dentro dele esto contidos trs
arquivos:
1. sakila-schema.sql: a estrutura da base de dados;
2. sakila-data.sql: so os dados da base de dados;
3. sakila.mwb: um projeto do MySQL workbench (http://wb.mysql.com/).
Vamos ento carregar os dois primeiros arquivos para o nosso SGBD. Para isso, abra o
MySQL Command Line Client, digite a senha do root e tecle <ENTER> para fazer o
login. Se estiver usando Linux, ou estiver com o bin do MySQL configurado no PATH
do Windows, faa o login no MySQL usando o comando mysql -u root -p (sem as
aspas). Quando estamos logados no interpretador do MySQL, podemos utilizar alguns
comandos para a administrao das bases de dados existentes. Um desses comandos o
source que utilizado para carregar e executar comandos do SGBD que esto
contidos em um arquivo de texto. Vamos utilizar ento este comando para carregar os
dois primerios arquivos do sakila database (a estrutura e os dados). Copiei os arquivos
sakila-schema.sql e sakila-data.sql para o C: para facilitar a digitao do comando. Veja

na Figura abaixo o comando sendo usado para a carga do primeiro arquivo (sakilaschema.sql).

Usando o comando source para carregar o arquivo sakila-schema.sql

Assim que voc digitar o comando source C:/sakila-schema.sql; (sem as aspas) e


teclar <ENTER>, voc vai ver que o interpretador do MySQL vai comear a processar o
arquivo, gerando vrias sadas. Se tudo der certo, uma base de dados chamada sakila
ser criada, bem como todas as tabelas da sua estrutura. Se quiser verificar que a base de
dados foi criada, basta dar o comando show databases; (sem as aspas) para listar as
bases de dados existentes.
Como exerccio, da mesma forma que voc carregou o arquivo sakila-schema.sql, voc
deve agora carregar o sakila-data.sql. Novamente os comandos sero processados e
agora, alm da estrutura da base de dados (criada no passo anterior), temos tambm
vrios dados para podermos utilizar em nossas consultas SQL e consequentemente em
nossos relatrios, mas antes de partirmos para os relatrios, vamos falar um pouquinho
da base de dados sakila. A seguir, uma imagem da estrutura da base, carregada no
MySQL Workbench (clique na imagem para ampliar).

Estrutura da base de dados sakila

Na base de dados sakila esto modeladas diversas tabelas que representam os dados de
uma locadora de DVDs fictcia. No vou ficar comentando cada tabela, pois apenas com
a leitura do diagrama voc vai conseguir entender os relacionamentos entre as elas,
afinal, se voc trabalha com bases de dados isso devere ser trivial :D.
Pronto! Agora sim! Vamos aos relatrios! Abra o NetBeans (se ainda no estiver
aberto) e carregue o projeto que criamos na Parte 1 do tutorial. Caso voc s tenha lido
o tutorial, no se preocupe, voc pode baixar o projeto feito na Parte 1 neste link. Com o
projeto aberto, expanda o n Relatrios do projeto. Voc vai notar a existncia do
default package (pacote padro). nele que vamos criar os arquivos de cdigo fonte
dos nossos relatrios. Sendo assim, clique com o boto direito neste pacote e escolha
New -> Other (Novo -> Outro). Veja a Figura abaixo.

Novo arquivo

Ao clicar em Other a janela de novo arquivo arquivo ser aberta. Em Categories


(Categorias) escolha Report (Relatrio) e em File Types (Tipos de Arquivo) escolha
Empty report (Relatrio vazio) e clique em Next (Prximo). Veja a Figura abaixo.

Novo arquivo fonte de relatrio

Ao clicar em Next, preencha o campo File Name (Nome do Arquivo) com Clientes
(sem as aspas) e clique em Finish (Finalizar/Terminar). Veja a Figura abaixo.

Criando o novo arquivo fonte de relatrio

Ao clicar em Finish, o arquivo de cdigo fonte do relatrio ser criado (Clientes.jrxml)


e a interface de edio do relatrio ser aberta, com o arquivo Clientes.jrxml carregado.
Note que neste primeiro relatrio, vamos simplesmente listar os dados de todos os
clientes, que por sua vez esto contidos na tabela customer da base de dados sakila.
Vamos agora conhecer a interface do editor do iReport. A Figura abaixo contm
diversas reas numeradas que sero explicadas logo seguir.

Interface grfica do editor WYSIWYG do iReport

1. Gerenciamento de Datasources (Fontes de Dados): A rea 1, destacada em


amarelo, utilizada para gerenciar os datasources que podem ser utilizados nos
testes dos relatrios que esto sendo criados;
2. rea de edio do relatrio: A rea 2, destacada em azul escuro, contm o
editor visual do relatrio (descrito no item 3 a seguir), alm de alguns botes
onde podemos visualizar o editor WYSIWYG (Design), o cdigo fonte do
relatrio (XML) e visualizar o relatrio sendo executado (Preview), alm de
podermos configurar a forma que o relatrio vai obter os dados que sero
obtidos atravz do datasource utilizado (primeiro boto aps o boto Preview);
3. Editor do relatrio: Essa rea utilizada para editar o formato do relatrio,
onde cada texto vai aparecer, quais bandas ele vai ter, etc. Existem vrios tipos
de bandas. As que so exibidas por padro so:
o Title: correponde ao cabealho do relatrio. Aparece somente na
primeira pgina;
o Page Header: cabealho da pgina. Aparece em todas as pginas;
o Column Header: cabealho das colunas. Aparece em todas as pginas;
o Detail: exibe os dados provenientes do datasource, ou seja, so os dados
que queremos mostrar no relatrio;
o Column Footer: rodap das colunas. Aparece em todas as pginas;
o Page Footer: rodap da pgina. Aparece em todas as pginas;
o Summary: resumo do relatrio. Aparece apenas na ltima pgina.
4. Paleta de componentes: Esta rea contm os componentes que podem ser
utilizados para montar o relatrio;

5. Propriedades: rea utilizada para exibir e editar as propriedades de um


componente que esteja selecionado;
6. Report Inspector: nesta rea que as configuraes do relatrio so acessadas,
como quais parmetros ele contm, quais os campos que so utilizados, quais
bandas esto visveis, etc.;
7. Sada (Output): Nesta rea so exibidos as sadas da execuo e compilao do
relatrio corrente.
Se a explicao de cada rea ficou confusa, no se preocupe. Voc vai entender tudo
daqui a pouco. Vamos comear ento a mexer no nosso primeiro relatrio. Primeiro
ento temos que configurar um datasource que vai trazer os dados de algum lugar. Note
que esse datasource utilizado apenas durante a edio do relatrio. Quando formos
executar o relatrio dentro de um programa, teremos que passar o datasource
programaticamente, mas isso ns vamos aprender depois. Pois bem, clique ento no
boto Report datasources (Fontes de dados do relatrio). Veja a Figura abaixo.

Boto Report datasources

Ao clicar neste boto, a janela de gerenciamento de datasources ser exibida. Por


padro, apenas um datasource vai estar configurado no iReport. Este datasource, o
Empty datasource (fonte de dados vazia) pode ser utilizado para visualizarmos apenas a
estrutura do relatrio. Vamos ento criar o datasource para a base de dados sakila. Para
isso, clique no boto New (Novo). Veja a Figura abaixo.

Gerenciador de datasources

Ao clicar em New, uma nova janela ser exibida. Nesta janela escolhemos o tipo de
datasource que vamos utilizar. No nosso caso, um Database JDBC connection, pois
iremos obter os dados no nosso relatrio utilizando uma query SQL, que por sua vez vai
ser executada atravs de uma conexo JDBC. Por padro, este tipo de datasource o
que vai estar selecionado no assistente. Caso no esteja selecionado, selecione-o e
clique em Next. Veja a Figura abaixo.

Escolhendo o tipo de datasource

Ao clicar em Next, a janela de configurao do datasource vai ser exibida. Nela


precisamos preencher alguns campos:

Name: nome do datasource. Utilize Sakila JDBC (sem as aspas);


JDBC Driver: o tipo de driver que vamos utilizar. No nosso caso, o driver do
MySQL;
JDBC URL: endereo do banco de dados que queremos utilizar. No nosso caso
jdbc:mysql://localhost/sakila (sem as aspas);
Username: nome do usurio. Estamos trabalhando em um ambiente de
desenvolvimento, ento vamos usar o root;
Password: senha do usurio. No meu caso a senha do root root tambm;
Save password: salvar a senha utilizada. Pode deixar marcada essa opo, se
no, toda hora que fizermos uma conexo, o iReport vai pedir a senha do
usurio.
Obs: os campos Server Address e Database so preenchidos apenas se voc
quiser usar o Wizard (boto Wizard) para preencher a URL de conexo. Como j

sabemos o formato da URL para o MySQL e j preenchemos o endereo, no


precisamos usar esses campos do Wizard.
Com tudo preenchido, clique em Save (Salvar). Veja a Figura abaixo.

Configurando o novo datasource

Ao salvar o datasource, a janela anterior ser exibida, mostrando que o novo datasource
foi configurado e est marcado como default (Padro). Clique em Close para fechar a
janela. Fazendo isso, voc vai ver que o combobox que contm os datasources estar
exibindo o datasource padro, ou seja, o Sakila JDBC que criamos. Isso significa
que quando formos criar uma query SQL no nosso relatrio ou formos execut-lo para
testar (Preview), o iReport vai usar o datasource que estiver selecionado neste combo.
Novamente, reforo a ideia que este datasource utilizado APENAS durante o
desenvolvimento do relatrio, seja na montagem de queries ou testes do relatrio.
Quando formos colocar o relatrio para ser aberto em nosso programa, teremos que

passar programaticamente o datasource que o nosso relatrio ir usar. Veja a Figura


abaixo.

Datasource "Sakila - JDBC" selecionado

Muito bem. Configuramos o datasource que vamos utilizar e ele j est selecionado.
Vamos agora ao relatrio. Vamos agora editar a query SQL do Clientes.jrxml. Para isso,
clique no boto que est destacado na Figura abaixo.

Acessando o editor de queries

Ao clicar no boto, a janela mostrada na Figura abaixo vai ser exibida.

Editor de queries

Nesta janela que vamos editar a query do nosso relatrio. Ao inserir a query, os
campos que ela retorna sero automaticamente carregados. Para este relatrio, queremos
listar todos os Clientes da locadora de DVDs, ento iremos usar a query SELECT *
FROM customer; (sem as aspas). Assim que a query for preenchida e executada com
sucesso, todos os campos que a execuo dela retornar sero carregados, sendo que
seus respecitvos tipos tambm sero obtidos. Veja a Figura abaixo.

Execuo da query e carga dos campos

Observando a Figura acima, voc pode perceber que ao executar a query informada
foram obtidos os campos customer_id (tipo Integer), store_id (tipo Integer), first_name
(tipo String) e assim por diante. Ao clicar em OK, esses campos (note que esto
selecionados) sero inseridos na definio do relatrio, bastando agora ns pegarmos
esses campos e inserir cada um deles, ou os que nos forem relevantes, no Design do
relatrio. Para pegar os campos, expanda o n Fields (Campos) do Report Inspector.
Veja a Figura abaixo.

Campos inseridos na definiao do relatrio

Suponha que queremos mostrar em nosso relatrio apenas o nome, o sobrenome e o email de cada cliente. Sendo assim, selecione primeiro o campo first_name e arraste
para a banda Detail do relatrio. Veja a Figura abaixo.

Iniciando a criao do relatrio

Note que onde voc soltou o campo fist_name (na bada Detail), foi inserida uma caixa
de texto do tipo Text Field (veja a paleta de componentes) com o valor $F{first_name},
onde $F denota o uso de um campo (F de Field) e o valor entre chaves o nome do
campo. Na banda Column Header foi inserida outra caixa de texto, s que apenas com o
valor first_name. Essa caixa de texto inserida no cabealho da coluna do tipo Static
Text, ou seja, um texto esttico. Vamos mudar ento o valor dessa segunda caixa para
Nome (sem as aspas) e organizar tanto a caixa de texto esttico quanto a de texto
dinmico. Veja a Figura abaixo.

Organizando o relatrio

Vamos testar agora o relatrio, afinal, queremos v-lo funcionando. Procure pelo boto
Preview e clique nele. O relatrio ser compilado e exibido. Veja a Figura abaixo.

Visualizando o relatrio

Legal, j estamos vendo os dados que vem do banco de dados no relatrio, mas afinal,
qual o motivo de um nome estar to distante do outro? O motivo que a banda Detail
est muito alta. A altura da banda Detail sempre vai ser replicada para cada registro
encontrado. Ento, para melhorar isso, vamos diminuir a altura da banda Detail. Volte
ento na visualizao no Designer (usando o boto Designer), selecione a linha azul no
limite inferior da banda Detail e arraste at chegar na altura desejada. Caso voc queira
que a banda fique com o tamanho do contedo dela (o que tem dentro dela), clique duas
vezes na linha azul. A banda vai ser redimensionada automaticamente. Veja a Figura
abaixo.

Banda detail redimensionada

Teste novamente o relatrio. Voc vai notar que agora os nomes esto mais perto um do
outro. Agora, como exerccio, arraste os campos last_name e email para o relatrio (na
banda Detail) e organize-os. Note que voc pode redimensionar cada campo tanto na
largura quanto na altura. Outra tarefa voltar ao editor da query do relatrio e inserir o
comando ORDER BY na query, para ordenar os registros pelo nome (first_name).
Quando fizer tudo isso e mandar visualizar, o resultado deve ser algo parecido com o
apresentado na Figura abaixo.

Relatrio atualizado

Vamos deixar agora o relatrio um pouco mais apresentvel. Da mesma forma que fez
com a banda Detail, diminua agora banda Colum Header. Clique com o boto direito na
banda Page Header e escolha Delete band. Na banda Title, insira uma caixa de texto
esttica, troque o valor do texto para Clientes Cadastrados (sem as aspas). Utilize o
editor de propriedades do componente (rea 5 da Figura onde so apresentadas as reas
do iReport) para configurar o tamanho da fonte do componente para 26, negrito (bold),
configure o alinhamento horizontal (horizontal alignment) para centro (center) e o
alinhamento vertical (vertical alignment) para meio (middle). Expanda o campo de texto
para ele ocupar toda a largura da pgina do relatrio. Configure os campos que definem
as colunas da banda detail (aqueles campos de texto contidos no cabealho) para
ficarem em negrito. Execute novamente o relatrio. Na Figura abaixo mostrado como
seu relatrio deve ter ficado no Preview.

Editando o relatrio

Para finalizar o design do nosso relatrio, vamos adicionar o nmero de pgina na


banda Page Footer. No Report Inspector, procure pelo n Variables e expanda-o. Uma
das variveis pr-configuradas se chama PAGE_NUMBER. Arraste-a para o lado
direito da banda Page Footer e configure o alinhamento horizontal do texto para a
direita (right). Dimensione a altura da banda Page Footer para ficar do tamanho do
campo que foi inserido. Delete as bandas Column Footer e Summary (clique com o
boto direito e escolha delete band em cada uma delas). O design do relatrio deve estar
como o da Figura abaixo.

Design final do relatrio

Teste seu relatrio e veja que o nmero da pgina ser exibido no final de cada pgina.
Note que o campo do campo de texto que foi inserido (um campo dinmico)
$V{PAGE_NUMBER}, sendo que o $V denota o uso de uma varivel e o valor entre
chaves o nome de varivel. Ainda vamos ver como criar variveis e parmetros
manualmente (ainda no falei dos parmetros).
Agora que j conseguimos criar nosso primeiro relatrio, ns vamos aprender um
detalhe muito importante que se conhecido, muitos problemas podem ser evitados.
Quando usamos uma query no editor de queries e o iReport cria automaticamente os
campos (Fields) para ns, ele atributi automaticamente um tipo para cada campo,
dependendo, claro, do tipo que aquele campo tem quando ele obtido. Ou seja,
first_name um campo VARCHAR na tabela customer, ento quando esse valor
obtido no iReport criado um campo, com o nome first_name (o nome que vem por
padro) do tipo String, que a representao para cadeias de caracteres em Java.
Quando queremos usar um campo no nosso relatrio, ns podemos arrastar ele
diretamente do Report Inspector para o relatrio que o iReport vai se preocupar em criar
um campo dinmico (Text Field na paleta) e inserir o valor $F{nome_do_campo}
dentro do campo dinmico. Um detalhe que no vemos acontecer, justamente porque o
iReport faz automticamente, a configurao do tipo do campo dinmico. O tipo do
campo dinmico tem que ser SEMPRE igual ao tipo do campo que utilizado.
Para entender o que eu falei, vamos fazer o seguinte teste. No relatrio que estamos
criando, arraste para a banda Detail na frente do campo para e-mail um campo
dinmico (Text Field na paleta). Por padro, o valor do campo vai ser $F{field}. Se
voc tentar executar o relatrio, o iReport vai reclamar, falando que o campo field no
existe. Isso uma verdade, visto que nenhum campo com o nome field foi criado no
mesmo? Vamos substituir o valor field para customer_id. O campo vai ficar ento com
o valor $F{customer_id}. Tente executar o relatrio para ver o que acontece.
Funcionou? No! Mas qual o motivo? O erro diz Cannot cast from Integer to String.
Isso quer dizer que o valor do campo customer_id um Integer e o JasperReports est
sendo instruido a fazer um cast explcito de Integer para String. Mas de onde vem essa
String? Lembram que falei que o campo dinmico (Text Field) tem que ter o mesmo

tipo de um campo? Ou seja, o campo customer_id do tipo Integer (inferido na criao


da query), enquanto o campo dinmico que est inserido no relatrio do tipo String. O
que temos que fazer? Mudar o tipo do campo dinmico. Para isso, selecione o campo
dinmico que est na banda Detail e procure pela propriedade expression class na
guia de propriedades do editor. O valor que estar l java.lang.String. Vamos mudar
para java.lang.Integer. Ao fazer isso, teste novamente o relatrio. Agora funcinou no
? Ento, tenha sempre em mente que o tipo de um campo dinmico tem que SEMPRE
SER DO MESMO TIPO que o campo ($F), a varivel ($V), o parmetro ($P), ou o
resultado de uma expresso que for executada na propriedade Text Field Expression do
campo dinmico.
Legal, agora ns vamos fazer esse relatrio ser executado a partir de um programa.
Lembram que eu falei que para um relatrio ser executado, ns precisaramos passar o
datasource que ns queremos que ele use? Pois bem, no nosso caso, o nosso datasource
uma conexo JDBC (java.sql.Connection), sendo assim, vamos precisar criar
conexes para passar para a engine de execuo do relatrio. Vamos ento criar uma
fbrica de conexes para utilizarmos. Essa fbrica uma classe, com o nome
ConnectionFactory. Para criar a classe, primeiramente v para a aba Projects do
NetBeans (canto superior esquerdo) expanda o n Source Packages (pacotes de cdigo
fonte) do nosso projeto, e no pacote tutorialrelatorios, crie um pacote chamado jdbc
(sem as aspas). Dentro ento do pacote jdbc, crie uma classe chamada
ConnectionFactory. Segue o cdigo comentado da classe.
tutorialrelatorios.jdbc.ConnectionFactory.java
1 package tutorialrelatorios.jdbc;
2 import java.sql.Connection;
3 import java.sql.DriverManager;
4 import java.sql.SQLException;
5
6 /**
7 * Uma fbrica de conexes.
*
8 * @author David Buzatto
9 */
10public class ConnectionFactory {
11
/*
12
* Este bloco esttico ser executado assim que esta classe for
13carregada,
14
* sendo assim, ser executado apenas uma vez.
15
*/
static {
16
try {
17
/*
18
* Carrega a classe com.mysql.jdbc.Driver, que a
19implementao
* do driver JDBC para o MySQL.
20
*/
21
Class.forName( "com.mysql.jdbc.Driver" );
22
23
// caso a classe no seja encontrada
24
} catch ( ClassNotFoundException exc ) {
25

/*
26
* Como log usaremos o stacktrace das excesses, mas
27
recomendo
28
* que para um projeto real voc utilize algum mecanismo
29de log
* melhor, como o Log4J por exemplo.
30
*/
31
exc.printStackTrace();
32
33
}
34
}
35
36
/**
* O mtodo getConnection retorna uma conexo com o banco de
37
dados
baseado
38
* nos parmetros fornecidos.
39
*
40
* @param url O endereo da base de dados.
* @param usuario O usurio que tem permisso na base de dados
41
42especificada.
* @param senha A senha do usurio especificado
43
* @return Uma conexo com o banco de dados especificado na url.
44
* @throws SQLException Caso ocorra algum problema durante a
45conexo.
*/
46
public static Connection getConnection(
47
String url,
48
String usuario,
49
String senha ) throws SQLException {
50
51
// retorna a conexo a partir do mtodo getConnection de
DriverManager
52
return DriverManager.getConnection( url, usuario, senha );
53
54
}
55
56
/**
57
* Obtm uma conexo para a base de dados sakila.
*
58
* @return Uma conexo para a base de dados sakila.
59
* @throws SQLException Caso ocorra algum problema durante a
60conexo.
61
*/
62
public static Connection getSakilaConnection() throws SQLException
63{
64
return getConnection(
65
"jdbc:mysql://localhost/sakila",
66
"root",
67
"root" );
68
}
69
70
71}
72
73
74

Usando o mtodo getSakilaConnection() iremos ento obter conexes para a base de


dados sakila, sendo que essa conexo ser utilizada pelo JasperReports para executar as
queries que forem definidas nos relatrios.
Alm da fbrica de conexes, vamos criar tambm uma classe que conter mtodos
utilitrios para abrir relatrios. Para isso, crie um pacote chamado utils (sem as aspas)
dentro do pacote tutorialrelatorios. Dentro do pacote criado, crie uma classe com o
nome de ReportUtils. Segue o cdigo comentado da classe.
tutorialrelatorios.util.ReportUtils.java
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

package tutorialrelatorios.util;
import
import
import
import
import
import
import
import
import
import

java.awt.BorderLayout;
java.io.InputStream;
java.sql.Connection;
java.util.Map;
javax.swing.JFrame;
net.sf.jasperreports.engine.JRDataSource;
net.sf.jasperreports.engine.JRException;
net.sf.jasperreports.engine.JasperFillManager;
net.sf.jasperreports.engine.JasperPrint;
net.sf.jasperreports.swing.JRViewer;

/**
* Classe com mtodos utilitrios para executar e abrir relatrios.
*
* @author David Buzatto
*/
public class ReportUtils {
/**
* Abre um relatrio usando uma conexo como datasource.
*
* @param titulo Ttulo usado na janela do relatrio.
* @param inputStream InputStream que contm o relatrio.
* @param parametros Parmetros utilizados pelo relatrio.
* @param conexao Conexo utilizada para a execuo da query.
* @throws JRException Caso ocorra algum problema na execuo
do relatrio
*/
public static void openReport(
String titulo,
InputStream inputStream,
Map parametros,
Connection conexao ) throws JRException {
/*
* Cria um JasperPrint, que a verso preenchida
relatrio,
* usando uma conexo.
*/
JasperPrint print = JasperFillManager.fillReport(
inputStream, parametros, conexao );
// abre o JasperPrint em um JFrame
viewReportFrame( titulo, print );

do

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

}
/**
* Abre um relatrio usando um datasource genrico.
*
* @param titulo Ttulo usado na janela do relatrio.
* @param inputStream InputStream que contm o relatrio.
* @param parametros Parmetros utilizados pelo relatrio.
* @param dataSource Datasource a ser utilizado pelo relatrio.
* @throws JRException Caso ocorra algum problema na execuo
do relatrio
*/
public static void openReport(
String titulo,
InputStream inputStream,
Map parametros,
JRDataSource dataSource ) throws JRException {
/*
* Cria um JasperPrint, que a verso preenchida
relatrio,
* usando um datasource genrico.
*/
JasperPrint print = JasperFillManager.fillReport(
inputStream, parametros, dataSource );

do

// abre o JasperPrint em um JFrame


viewReportFrame( titulo, print );
}
/**
* Cria um JFrame para exibir o relatrio representado pelo
JasperPrint.
*
* @param titulo Ttulo do JFrame.
* @param print JasperPrint do relatrio.
*/
private static void viewReportFrame( String titulo, JasperPrint
print ) {
/*
* Cria um JRViewer para exibir o relatrio.
* Um JRViewer uma JPanel.
*/
JRViewer viewer = new JRViewer( print );
// cria o JFrame
JFrame frameRelatorio = new JFrame( titulo );
// adiciona o JRViewer no JFrame
frameRelatorio.add( viewer, BorderLayout.CENTER );
// configura o tamanho padro do JFrame
frameRelatorio.setSize( 500, 500 );
// maximiza o JFrame para ocupar a tela toda.
frameRelatorio.setExtendedState( JFrame.MAXIMIZED_BOTH );

// configura a operao padro quando o JFrame for fechado.


90
frameRelatorio.setDefaultCloseOperation(
91
JFrame.DISPOSE_ON_CLOSE );
92
93
// exibe o JFrame
94
frameRelatorio.setVisible( true );
95
}
96
97
98 }
99
100
101
102
103
104
105
106
107
108
109

No vamos criar uma interface grfica para executar nosso relatrio, pois vamos abri-lo
diretamente da classe Main do projeto. Perceba que o cdigo usado na classe Main o
mesmo que voc vai utilizar, por exemplo, para abrir o relatrio a partir do clique de um
boto, mas antes disso, mais alguns detalhes. Quando fazemos o preview do relatrio, o
iReport invoca o compilador do JasperReports para compilar o arquivo .jrxml em um
arquivo .jasper, para ento executar o arquivo .jasper, abrindo assim o relatrio. Voc
deve ter percebido que agora, alm do arquivo Clientes.jrxml, existe tambm o arquivo
Clientes.jasper na nossa pasta de definies de relatrios. Se voc quiser compilar
manualmente um relatrio sem entrar no preview do mesmo, basta ir no Report
Inspector, com o relatrio desejado aberto, clicar com o boto direito no n raiz do
relatrio, que por padro tem o nome de report name (nome do relatrio) e escolher
Compile Report (Compilar Relatrio).
Vamos ento executar nosso relatrio a partir do mtodo main da classe Main do nosso
projeto. Segue o cdigo comentado da classe.
1 package tutorialrelatorios;
2 import java.io.InputStream;
3 import java.sql.SQLException;
4 import java.util.HashMap;
5 import java.util.Map;
6 import net.sf.jasperreports.engine.JRException;
import tutorialrelatorios.jdbc.ConnectionFactory;
7 import tutorialrelatorios.util.ReportUtils;
8
9 /**
10 * Ponto de entrada do projeto.
11 *
12 * @author David Buzatto
*/
13public class Main {

14
/**
15
* @param args the command line arguments
16
*/
17
public static void main(String[] args) {
18
new Main().abrirRelatorioClientes();
}
19
20
public void abrirRelatorioClientes() {
21
22
/*
23
* Obtendo o arquivo do relatrio.
24
* Note que estamos utilizando um InputStream para obter o
25arquivo que
* est dentro do nosso projeto. Fazendo isso, no teremos
26
problema
27
* quando nosso projeto for empacotado em um .jar.
28
*
29
* Note que o caminho do .jasper inicia com /, ou seja, a
30raiz da
* localizao das classes compiladas do nosso projeto
31
* (o pacote default).
32
*
33
* Utilize a aba Files (canto superior esquerdo) e veja que
34os arquivos
* .jasper e .jrxml so
copiados para o
diretrio
35
/build/classes
36
* e por consequencia para o .jar que for criado.
37
*
38
* Se no os estiver vendo, mande dar um Clean and Build no
39projeto
* (boto direito no n raiz do projeto, Clean and Build
40
(Limpar
e
Construir)
41
*
42
*/
43
InputStream inputStream = getClass().getResourceAsStream(
44"/Clientes.jasper" );
45
// mapa de parmetros do relatrio (ainda vamos aprender a
46
usar)
47
Map parametros = new HashMap();
48
49
try {
50
51
// abre o relatrio
ReportUtils.openReport(
"Clientes",
inputStream,
52
53parametros,
ConnectionFactory.getSakilaConnection() );
54
55
} catch ( SQLException exc ) {
56
exc.printStackTrace();
} catch ( JRException exc ) {
57
exc.printStackTrace();
58
}
59
60
}
61
62}
63

64
Tente executar o projeto teclando F6. Uma excesso ser lanada
(java.lang.ClassNotFoundException: com.mysql.jdbc.Driver). Isso se deve ao fato de
que ns ainda no colocamos o driver do MySQL no nosso projeto! Clique ento em
Libraries com o boto direito e escolha Add Library. Como as bibliotecas do nosso
projeto ficam inseridas no projeto e no nas configuraes do NetBeans, temos que criar
a biblioteca como fizemos com o JasperReports e suas dependncias. Mas ao invs de
fazer todo aquele processo na mo, ns podemos importar bibliotecas que esto
configuradas no NetBeans sendo que o driver do MySQL uma delas. Sendo assim, na
janela que se abriu, clique no boto Import. Ao fazer isso, a janela Import Library ir
aparecer. Procure pela biblioteca MySQL JDBC Driver, selecione-a e clique no boto
Import Library. Com isso a biblioteca do driver do MySQL ser importada para o
projeto. Voc vai ver ela na janela que apareceu novamente. Selecione-a e clique em
Add Library. Aps fazer isso, tecle F6 novamente para executar o projeto.
Agora sim, uma janela com o relatrio ser aberta. Experimente utilizar os controles da
janela, tente salvar o relatrio em vrios formatos, etc. Aps brincar um pouco com
isso, feche a janela e vamos a mais algumas explicaes para finalizarmos esta parte do
tutorial.
Ao ler os comentrios da classe Main, voc deve ter percebido duas coisas. Primeiro, o
arquivo .jrxml est sendo copiado para a estrutura compilada do nosso projeto (build) e
por consequncia, o arquivo .jrxml vai ser empacotado no .jar, sendo que s queremos
distribuir o arquivo compilado (.jasper). Segundo, ainda no aprendemos a utilizar o
mapa de parmetros e ainda no foi explicado qual a sua utilidade.
Em relao ao primeiro problema, para excluir certos tipos de arquivos do processo de
build, abra as propriedades do projeto e localize o n Packaging, dentro do n Build. Ao
clicar nesta opo, voc vai ver um campo chamado Exclude From JAR File. Neste
campo, voc informa o padro de nome dos arquivos que voc NO QUER que sejam
inseridos no build. Por padro, o valor **/*.java,**/*.form, ou seja, qualquer
arquivo, de qualquer diretrio do projeto que tenha extenso java e qualquer arquivo,
de qualquer diretrio do projeto que tenha extenso form. Precisamos inserir ento
nessa lista os arquivos de extenso jrxml. Para fazer isso, basta adicionar um item na
lista com o valor **/*.jrxml (sem as aspas). O valor final do campo deve ser
**/*.java,**/*.form, **/*.jrxml (sem as aspas). Ao fazer isso, clique em OK e mande
limpar e refazer o build no projeto (boto direito no n raiz do projeto, opo Clean and
Build Limpar e Construir). V novamente na aba Files (canto superior esquerdo) e
expanda a pasta /build/classes. Voc vai ver que agora somente o arquivo .jasper est
sendo copiado para o build.
Tudo bem at aqui? Espero que sim. Estamos acabando. Agora vamos a parte final, os
parmetros.
Quando criamos listagens de dados em relatrios, normalmente ns queremos filtrar tais
dados, nos baseando em alguma restrio. Imagine que no nosso relatrio de clientes,
ns queiramos filtrar os clientes existentes a partir do primeiro nome deles. Para isso,
teremos que inserir uma restrio na query do relatrio para comparar o primeiro nome
com o valor que queremos filtrar. Modificar a query fcil, mas ns precisamos que

esse valor que ser utilizado na query seja dinmico, ou seja, a cada vez que
executarmos o relatrio, queremos que o valor de restrio seja diferente. Para utilizar
esses valores dinmicos no iReport, ns usamos os chamados parmetros. Vamos ento
fazer uma cpia do nosso primeiro relatrio para inserirmos esse tipo de restrio.
Na aba Projects, procure pelo arquivo Clientes.jrxml na pasta de definies de
relatrios. Clique com o boto direito nele e escolha Copy (Copiar). Clique com o boto
direito no pacote default da pasta de definies de relatrios e escolha Paste (Colar). O
arquivo ser colado com o nome de Clientes_1.jrxml. Selecione o arquivo, tecle F2 (ou
boto direito, rename renomear) e troque o nome para ClientesPorNome.jrxml. Ao
fazer isso, abra o ClientesPorNome.jrxml no editor de relatrios.
Com o arquivo aberto, v no Report Inspector e procure pela banda Page Header que
estar sendo exibida em cinza claro. Est assim porque ela foi removida lembra? Para
fazer ela aparecer novamente no relatrio, clique com o boto direito nela e escolha Add
Band (Adicionar Banda). Ainda no vamos mexer com essa banda, mas s para
adiantar, ela vai ser utilizada para mostrar o filtro que estamos fazendo.
Ainda no Report Inspector, procure pelo n Parameters (Parmetros) e expanda-o.
Voc vai ver que existem diversos parmetros pr-configurados no nosso relatrio. Ns
queremos criar mais um. Para isso, clique com o boto direito em Parameters e escolha
Add Parameter. Um novo parmetro, com o nome parameter1 vai ser criado.
Selecione-o e troque o nome dele para primeiroNome. Perceba que ao selecionar um
parmetro, o editor de propriedades do iReport mostra diversas propriedades, entre elas
a classe do parmetro (Parameter Class). Da mesma forma que os campos e variveis
do relatrio, os parmetros tambm precisam de um tipo. Este parmetro que estamos
criando vai ser utilizado no filtro da query, ou seja, ele vai conter o valor que queremos
utilizar como filtro. Um nome uma String no ? Ento a classe desse parmetro a
java.lang.String mesmo, mas imagine que queiramos comprar um nmero. Ento a
classe teria que ser de algum tipo numrico ok?
Note tambm que a propriedade Use as prompt deve estar selecionada. Essa
propriedade utilizada para que quando formos dar o preview no relatrio, seja aberto
um dilogo para pedir o valor que queremos que o parmetro assuma naquela execuo.
Execute o relatrio para ver isso acontecer. Veja a Figura abaixo.

Prompt de parmetro

Mesmo que voc informe qualquer valor para o parmetro, o resultado do relatrio vai
ser o mesmo, afinal, no inserimos o parmetro na query do relatrio no mesmo?
Vamos fazer isso agora. Abra o editor de queries do relatrio e edite a query para ficar
assim:
1SELECT * FROM customer
2WHERE first_name LIKE $P{primeiroNome}
3ORDER BY first_name;
Aps editar, clique em OK. Note que foi inserido uma clusula WHERE na query,
comparando o campo first_name com o valor do parmetro, usando o operador LIKE.
Note que para utilizarmos o valor do parmetro, utilizamos a notao
$P{nomeDoParametro}. Imagine que na hora da execuo, o parmetro assuma o
valor D%, ou seja, queremos qualquer cliente com o nome que inicie com a letra D. A
query na hora da execuo ficaria assim:
1SELECT * FROM customer
2WHERE first_name LIKE 'D%'
3ORDER BY first_name;
Perceberam o que estamos fazendo? Note que as aspas simples sero inseridas
automaticamente pelo JasperReports na hora da execuo, pois o parmetro
primeiroNome uma String. Teste o relatrio e passe no valor do parammetro como
D% (sem as aspas). O resultado deve estar parecido com o da Figura abaixo.

Resultado do relatrio passando D% no valor do parmetro

Legal no ? Ento caso voc queira inserir mais restries no relatrio, basta criar mais
parmetros e ir modificando a query. Faa mais alguns testes ;). Vamos agora mostrar
para o usurio qual foi a restrio que foi pedida no relatrio. Lembram da banda Page
Header que colocamos novamente no relatrio? Insira nela um campo de texto esttico
(Static Text) e preencha-o com o valor Com nome: (sem as aspas), alinhe o texto
direita e escolha para ficar em negrito (bold). Na frente deste campo, insia um campo
dinmico (Text Field) e edite seu valor para $P{primeiroNome} (sem as aspas).
Percebeu o que estamos fazendo? Vamos mostrar o valor do parmetro no relatrio
tambm! Lembre-se que o tipo do campo dinmico tem que ser o mesmo do valor que
ele vai mostrar, no caso uma String, que o tipo do parmetro primeiroNome.
Coloquei tambm algumas linhas (componente Line da paleta) no relatrio para ficar
mais bonitinho ;). Veja a Figura abaixo para ver como ficou.

Design do relatrio finalizado

Muito bem! Agora, para que este novo relatrio funcione corretamente quando formos
utiliz-lo no nosso programa, ns precisamos passar o parmetro que foi configurado
no mesmo? Lembram do mapa de parmetros que foi criado? Do tipo Map<String,
Object>? nele que passamos o valor dos parmetros. A chave do mapa uma String,
que vai corresponder ao nome do parmetro (no nosso caso, primeiroNome). O valor do
item do mapa um Object, mas precisamos passar instncias de objetos que casem com
o tipo do parmetro configurado no relatrio. No nosso caso, primeiroNome do tipo
String lembram? Ento o objeto que tem que ser passado no valor do item do mapa
precisa ser uma String, por causa do tipo do parmetro como j falei. Veja o cdigo
alterado do mtodo abrirRelatorioClientes() da classe Main.
1 public void abrirRelatorioClientes() {
2
// note que estamos chamando o novo relatrio
3
InputStream
inputStream
=
getClass().getResourceAsStream(
4 "/ClientesPorNome.jasper" );
5
6
// mapa de parmetros do relatrio
Map parametros = new HashMap();
7
8
/*
9
* Insere o parmetro primeiroNome no mapa, com o valor F%
10
* ou seja, todos os clientes que tenham primeiro nome comeando
11
* com a letra F.
12
*/
parametros.put(
"primeiroNome", "F%" );
13
14
// outros possveis parmetros aqui...
15
16
try {
17
18
// abre o relatrio
19
ReportUtils.openReport( "Clientes", inputStream, parametros,
ConnectionFactory.getSakilaConnection() );
20

21
22
23
24
25
26
27}
28
29
30

} catch ( SQLException exc ) {


exc.printStackTrace();
} catch ( JRException exc ) {
exc.printStackTrace();
}

Perceba que caso existam mais parmetros a serem enviados ao relatrio, eles devem ser
inseridos no mesmo mapa. Outro detalhe que estamos apenas fazendo um exemplo e
passando um valor fixo no parmetro. Em um caso real, o valor a String F% viria de
um campo de texto ou qualquer outro componente da sua interface grfica.
Com isso terminamos a segunda parte do nosso tutorial. Espero que tenham gostado :).
Na prxima parte iremos aprender a trabalhar com os temidos subrelatrios :D. Digo
temidos porque so um pouco chatos de usar e se voc no souber realmente o que
est fazendo e como eles funcionam, voc pode ficar um dia inteiro tentando fazer
funcionar e no conseguir :(
Neste link voc pode fazer o download do cdigo fonte do projeto at o momento.
Ento isso ai. Um grande abrao!
Parte 1 Parte 2 Parte 3 Parte 4 Parte 5

JasperReports: Trabalhando com Relatrios em Java


Parte 3 (Subrelatrios)
Filed under: Desktop, Java, Programao, Relatrios 23 Comentrios
14/10/2010

16 Votes

Parte 1 Parte 2 Parte 3 Parte 4 Parte 5


Ol! Hoje vamos aprender a trabalhar com subrelatrios no JasperReports, mas antes de
comear quero explicar algumas coisas. Nos ltimos posts, eu tenho tentado formatar os
termos em ingls em itlico e colocar logo em seguida a traduo. Eu vou parar de fazer
isso. Primeiro, pq os termos so simples, e qualquer pessoa que trabalhe com
informtica tem mais que obrigao de saber. Segundo, gasto muito tempo formatando
cada pargrafo, revisando se est tudo ok, etc. Ento, para agilizar o processo, estou
deixando de lado essa prtica. Tenho tambm tratado os leitores cada hora de um jeito.
Uma hora escrevo na primeira pessoa do singular, na outra, escrevo na terceira do
plural. Vou tentar manter a mesma narrao, mas se eu cometer algum deslize, no se
encomodem ok? Ento, vamos comear!
Se voc j tentou trabalhar com subrelatrios, provavelmente teve algumas frustraes
at conseguir fazer funcionar. Se voc nunca trabalhou, hoje vai aprender! Trabalhar
com subrelatrios no difcil, o problema entender como as coisas funcionam, mas
antes de falar disso, vamos nos situar no tema. O que um subrelatrio? Como o
prprio nome diz um relatrio que fica dentro de um outro relatrio, ou seja, uma
parte de um relatrio maior, mais geral. Vamos entender por meio de um exemplo. Para
isso, abra o diagrama da base de dados sakila clicando aqui e imagine a seguinte
situao: voc precisa criar um relatrio, onde sero exibidos os dados de todos os
clientes e de todos os filmes que cada um alugou. O layout do relatrio teria que ficar
mais ou menos assim:

Rascunho do layout do relatrio de filmes por cliente

Como criar um relatrio com esse layout? Usando subrelatrios! A parte mais externa
do layout representa o arquivo de relatrio mais geral, onde sero listados os clientes e
onde ser inserido o subrelatrio. O subrelatrio, destacado em azul, ser um outro
arquivo de relatrio que ser utilizado dentro do relatrio mais geral. Confuso? Calma,
calma, logo vocs vo enteder. Antes disso, um pouquinho mais de teoria.
O funcionamento de um subrelatrio igual ao de um relatrio normal, sendo que existe
apenas uma diferena e justamente aqui que as pessoas se confundem. Os parmetros
de um subrelatrio no so enviados diretamente do cdigo Java como feito em um
relatrio normal. No caso dos subrelatrios, os parmetros so enviados pelo relatrio
que os contm, para ento serem passados ao subrelatrio. Ento, caso voc passe um
parmetro para o relatrio que deve ser usado apenas no subrelatrio, o seu relatrio vai
ter que ter o mesmo parmetro e voc vai ter que criar essa ponte entre o relatrio
principal e o subrelatrio. Veja a Figura abaixo.

Parmetros sendo passados entre as camadas de relatrios

Em vermelho destacada a transmisso dos parmetros a partir da aplicao em Java


para o relatrio. Esses parmetros so enviados usando o mapa da parmetros lembram?
Em laranja destacada a transmisso dos parmetros para o subrelatrio a partir do
relatrio. Veja ento que o relatrio vai servir de ponte entre os parmetros desejados,
alm de poder criar novos parmetros e os enviar para o subrelatrio. Outro detalhe
que podem haver diversos nveis de relatrios, ou seja, um subrelatrio pode enviar
parmetros para um subsubrelatrio, um subsubrelatrio pode enviar parmetros para
um subsubsubrelatrio, e assim por diante.
Finalmente! Vamos prtica! Abra o NetBeans e o projeto que estamos usando
(TutorialRelatorios). Se voc no acompanhou a parte anterior do tutorial, ou mesmo
que tenha acompanhado e no tenha feito o exemplo, voc pode baixar a verso do
projeto (finalizada na Parte 2) clicando aqui. Na pasta de definies de relatrios que
criamos, crie um novo Empty Report e d o nome de LocacoesPorClientes. O arquivo
LocacoesPorClientes.jrxml vai ser criado. Caso ele no abra automaticamente no editor,
clique duas vezes para ser carregado no iReport.

Com o arquivo aberto, vamos primeramente criar um relatrio simples, que lista os
clientes a partir de uma pesquisa pelo nome. A query deste relatrio vai ser um pouco
mais complexa que a do relatrio ClientesPorNome, criado na Parte 2 do tutorial, pois
nela iremos obter outros dados do cliente que no esto na tabela customer. No se
esquea de escolher o datasource correto, o Sakila JDBC ok? Crie tambm um
parmetro, do tipo String, com o nome de nomeCliente. Segue ento a query que deve
ser inserida no relatrio:
1 SELECT
c.customer_id idCliente,

c.first_name nome,

c.last_name sobrenome,

c.email email,

5
a.address endereco,

a.phone telefone,

ci.city nomeCidade,

co.country nomePais

9
10FROM
11

customer c,

12

address a,

13
14

city ci,
country co

15
WHERE

16
/* junes */

17
18
19

c.address_id = a.address_id AND


a.city_id = ci.city_id AND
ci.country_id = co.country_id AND

20
21

/* restries */

22

c.first_name LIKE $P{nomeCliente}

23

24ORDER BY c.first_name;
25
26

Ao inserir a query, o iReport vai carregar os campos retornados por ela. Ao clicar em
OK, os campos carregados sero criados na definio do relatrio. Os fields lembram?
Expanda ento o n Fields do Report Inspector e arraste e organize esses campos na
banda Detail do relatrio. Veja como ficou o meu.

Layout do relatrio de locaes por clientes

Note que coloquei campos estticos na banda Detail, tirei as bandas Column Header,
Column Footer e Summary. Criei um parmetro chamado nomeUsuario para mostrar
no cabealho da pgina o nome do usurio do sistema que gerou o relatrio. Outra
coisa que fiz foi colocar a data e hora que o relatrio foi gerado na banda Page Header.
Note que para o uso da data e do formato, foi usado um campo de texto dinmico, com
o tipo java.util.Date e a propriedade pattern alterada para dd/MM/yyyy, s
HH:mmhs' (sem as aspas). Note tambm que o valor deste campo gerado a partir de
um cdigo Java! Segue o fonte em XML do relatrio. Basta copiar e colar no seu
relatrio (usando o boto XML).
LocacoesPorClientes.jrxml

1 <?xml version="1.0" encoding="UTF-8"?>


2 <jasperReport
xmlns="http://jasperreports.sourceforge.net/jasperreports"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperrepor
http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
4 ts
name="report name" pageWidth="595" pageHeight="842" columnWidth="535"
5 leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">

<property name="ireport.zoom" value="1.0"/>

<property name="ireport.x" value="0"/>


<property name="ireport.y" value="0"/>

<parameter name="nomeCliente" class="java.lang.String"/>

<parameter name="nomeUsuario" class="java.lang.String"/>

10

<queryString>

11

<![CDATA[SELECT

12

c.customer_id idCliente,

13

c.first_name nome,

14

c.last_name sobrenome,

15

c.email email,

16

a.address endereco,
a.phone telefone,

17

ci.city nomeCidade,

18

co.country nomePais

19
20
FROM

21
22

customer c,
address a,

23

city ci,

24

country co

25
26 WHERE
27

/* junes */

28

c.address_id = a.address_id AND

29

a.city_id = ci.city_id AND

30

ci.country_id = co.country_id AND

31
32

/* restries */
c.first_name LIKE $P{nomeCliente}

33
34
ORDER BY c.first_name;]]>

35
36

</queryString>
<field name="idCliente" class="java.lang.Integer"/>

37

<field name="nome" class="java.lang.String"/>

38

<field name="sobrenome" class="java.lang.String"/>

39

<field name="email" class="java.lang.String"/>

40

<field name="endereco" class="java.lang.String"/>

41
42

<field name="telefone" class="java.lang.String"/>


<field name="nomeCidade" class="java.lang.String"/>
<field name="nomePais" class="java.lang.String"/>

43
<background>

44
45
46
47
48
49
50
51

<band splitType="Stretch"/>
</background>
<title>
<band height="75" splitType="Stretch">
<staticText>
<reportElement x="0" y="18" width="555" height="40"/>
<textElement
verticalAlignment="Middle">

textAlignment="Center"

<font size="25" isBold="true"/>

52

</textElement>

53

<text><![CDATA[Locaes por Clientes]]></text>

54

</staticText>

<line>

55

<reportElement x="0" y="1" width="555" height="1"/>

56

</line>

57

<line>

58

<reportElement x="0" y="74" width="555" height="1"/>

59
</line>

60
61
62

</band>
</title>
<pageHeader>

63

<band height="21" splitType="Stretch">


<staticText>

64

<reportElement x="-1" y="0" width="51" height="20"/>

65
66

<textElement
verticalAlignment="Middle">

67

textAlignment="Left"

<font isBold="true"/>

68

</textElement>

69

<text><![CDATA[Usurio:]]></text>

70

</staticText>

71

<textField>
<reportElement x="53" y="0" width="150" height="20"/>

72

<textElement verticalAlignment="Middle"/>

73

<textFieldExpression

74 class="java.lang.String"><![CDATA[$P{nomeUsuario}]]></textFieldExpre
ssion>

75
</textField>

76
77
78
79

<staticText>
<reportElement x="360" y="0" width="68" height="20"/>
<textElement
verticalAlignment="Middle">

textAlignment="Left"

<font isBold="true"/>

80
</textElement>

81

<text><![CDATA[Gerado em:]]></text>

</staticText>

82
83

<textField
HH:mm&apos;hs&apos;">

84

s&apos;

<reportElement x="433" y="0" width="122" height="20"/>

85
86

pattern="dd/MM/yyyy&apos;,

<textElement verticalAlignment="Middle"/>
<textFieldExpression
class="java.util.Date"><![CDATA[new Date()]]></textFieldExpression>

87
</textField>

88
89
90
91
92
93
94
95

</band>
</pageHeader>
<detail>
<band height="110" splitType="Stretch">
<staticText>
<reportElement x="0" y="3" width="50" height="20"/>
<textElement
verticalAlignment="Middle">
<font isBold="true"/>

96

</textElement>

97

<text><![CDATA[Nome:]]></text>

98

</staticText>

99

<textField>

10
0

textAlignment="Left"

<reportElement x="0" y="23" width="99" height="20"/>


<textElement verticalAlignment="Middle"/>

<textFieldExpression
10
1 class="java.lang.String"><![CDATA[$F{nome}]]></textFieldExpression>

10
2
10
3
10
4
10

</textField>
<staticText>
<reportElement x="103" y="3" width="70" height="20"/>
<textElement
verticalAlignment="Middle">
<font isBold="true"/>
</textElement>

textAlignment="Left"

<text><![CDATA[Sobrenome:]]></text>

5
10
6

</staticText>
<textField>

10
7 height="20"/>

<reportElement

10
8

<textElement verticalAlignment="Middle"/>

x="103"

y="23"

width="136"

<textFieldExpression
class="java.lang.String"><![CDATA[$F{sobrenome}]]></textFieldExpress
10 ion>

9
</textField>

11
0
11
1

<staticText>
<reportElement x="242" y="3" width="70" height="20"/>
<textElement
verticalAlignment="Middle">

11
2

<font isBold="true"/>
</textElement>

11
3
11
4

textAlignment="Left"

<text><![CDATA[E-mail:]]></text>
</staticText>
<textField>

11
5 height="20"/>

<reportElement

11
6

<textElement verticalAlignment="Middle"/>

11
7
11
8

x="242"

12
1
12

width="228"

<textFieldExpression
class="java.lang.String"><![CDATA[$F{email}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="0" y="47" width="59" height="20"/>

11
<textElement
9 verticalAlignment="Middle">
12
0

y="23"

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[Endereo:]]></text>
</staticText>

<textField>

<reportElement x="62" y="47" width="177" height="20"/>

12
3

<textElement verticalAlignment="Middle"/>

12
<textFieldExpression
4 class="java.lang.String"><![CDATA[$F{endereco}]]></textFieldExpressi
on>

12
5
12
6

</textField>
<staticText>
<reportElement x="473" y="3" width="82" height="20"/>

12
7

<textElement verticalAlignment="Middle">

12
8

</textElement>

12
9

<font isBold="true"/>

<text><![CDATA[Telefone:]]></text>
</staticText>
<textField>

13
0

<reportElement x="473" y="23" width="82" height="20"/>


<textElement verticalAlignment="Middle"/>

13
1

<textFieldExpression
class="java.lang.String"><![CDATA[$F{telefone}]]></textFieldExpressi
13 on>

2
13
3

</textField>
<staticText>
<reportElement x="242" y="47" width="42" height="20"/>

13
4

<textElement
verticalAlignment="Middle">

13
5

<font isBold="true"/>
</textElement>

13
6
13
7

textAlignment="Left"

<text><![CDATA[Cidade:]]></text>
</staticText>
<textField>

13
8 height="20"/>

<reportElement

13

<textElement verticalAlignment="Middle"/>

x="287"

y="47"

width="106"

<textFieldExpression
class="java.lang.String"><![CDATA[$F{nomeCidade}]]></textFieldExpres
14 sion>

0
14
1

</textField>
<staticText>
<reportElement x="397" y="47" width="31" height="20"/>

14
2

<textElement
verticalAlignment="Middle">

14
3

textAlignment="Left"

<font isBold="true"/>
</textElement>

14
4
14
5

<text><![CDATA[Pas:]]></text>
</staticText>
<textField>

14
height="20"/>
6

<reportElement

x="433"

y="47"

width="122"

<textElement verticalAlignment="Middle"/>

14
7

<textFieldExpression
class="java.lang.String"><![CDATA[$F{nomePais}]]></textFieldExpressi
14 on>

8
14
9

</textField>
<staticText>
<reportElement

15 height="20"/>
0

x="167"

<textElement
15 verticalAlignment="Middle" rotation="None">

textAlignment="Center"

</textElement>

<text><![CDATA[O
aqui....]]></text>
15

</staticText>

15
4

<line>

Subrelatrio

vai

<reportElement x="0" y="1" width="555" height="1"/>


</line>
</band>

15

width="226"

<font size="12" isBold="true"/>

15
2

15
5

y="82"

vir

</detail>

15
7

<pageFooter>
<band height="22" splitType="Stretch">

15
8

<textField>
<reportElement x="455" y="2" width="100" height="20"/>

15
<textElement
9 verticalAlignment="Middle"/>

textAlignment="Right"

16
<textFieldExpression
class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpr
0
ession>

16
1
16
2
16
3
16
4
16
5
16
6
16
7
16
8
16
9
17
0
17
1
17
2
17

</textField>
<line>
<reportElement x="0" y="1" width="555" height="1"/>
</line>
</band>
</pageFooter>
</jasperReport>

3
17
4
17
5
17
6
17
7
17
8
17
9
18
0
18
1
18
2
18
3
18
4
18
5
18
6
18
7
18
8
18
9
19

0
19
1
19
2
19
3
19
4
19
5
19
6
19
7
19
8
19
9
20
0
20
1
20
2

Depois de colar, volte para o Designer e verifique o que foi feito em cada parte. Aps
atualizar o seu relatrio, teste-o. O iReport vai pedir dois parmetros, o nomeCliente
que vai ser usado na query e o nomeUsuario que vai ser usado no pageHeader. Note que
coloquei um campo de texto esttico na banda detail, mostrando onde vai ficar o
subrealtrio. Vamos cri-lo ento. Primeiro, remova o campo de texto esttico que tem
o valor O Subrelatrio vai vir aqui e aumente a banda detail na altura cerca de 120
pixels (depois iremos deixar do tamanho correto). Na paleta de componentes, procure
por Subreport. Arraste m subreport para a banda Detail. Assim que arrastar e soltar, o
assistente de criao de subrelatrios ir abrir. No primeiro passo, escolha Create a
new report e clique em Next. Veja a Figura abaixo.

Primeiro passo do assistente de subrelatrio

No segundo passo, escolha o layout como Blank A4 e clique em Next. Veja a Figura
abaixo.

Segundo passo do assistente de subrelatrio

No terceiro passo, ele vai pedir para inserir uma query. Iremos colocar uma query
provisria, s para poder continuar o assistente. Depois iremos mud-la. Coloque
SELECT * FROM country (sem as aspas) e clique em Next. Veja a Figura abaixo.

Terceiro passo do assistente de subrelatrio

No quarto passo, ele vai perguntar os campos que queremos usar. No adicione
nenhum, pois no vamos us-los, pois essa no a query que queremos lembram? Veja
a Figura abaixo.

Quarto passo do assistente de subrelatrio

No quinto passo, o assistente pergunta os grupos que sero usados. Ns no usaremos


grupos, ento, da mesma forma que fizemos no passo anterior, clique em Next sem
fazer nada. Veja a Figura abaixo.

Quinto passo do assistente de subrelatrio

No prximo passo, configuramos o nome do arquivo de relatrio que vai ser gerado
(Report Name), onde ele vai ser armazenado e como ele vai ser obtido no relatrio
principal. Sendo assim, em Report Name insira LocacoesPorClientes_Locacoes (sem
as aspas). No mexa em Location, pq j deve estar apontanto para o diretrio do
relatrio principal. Abaixo, escolha Store the directory name in a parameter. Isso vai
ser til depois, para informarmos onde est o subrelatrio. Feito isso, clique em Next.
Veja a Figura abaixo.

Sexto passo do assistente de subrelatrio

No stimo e ltimo passo perguntado como os dados do subrelatrio sero obtidos.


Marque a opo Use the same connection used to fill the master report, ou seja,
vamos usar o mesmo objeto Connection passado para executar a query do relatrio
principal. Clique em Finish. Veja a Figura abaixo.

Stimo passo do assistente de subrelatrio

Ao clicar em Finish, o novo arquivo de relatrio ser criado e aberto. Mas ainda no
vamos mexer nele. Volte ao relatrio principal. Voc vai perceber que foi inserida uma
caixa cinza no relatrio. Essa caixa indica onde o subrelatrio vai ser inserido. Note
ento que para cada cliente, teremos um subrelatrio renderizado, afinal, estamos na
banda Detail no mesmo? Expanda a caixa na largura, para ocupar quase a totalidade
do relatrio e altere a largura da banda detail acomodar a caixa do subrealtrio. Veja a
Figura abaixo.

Layout do relatrio principal

Ainda no teste o relatrio! Como estamos obtendo todos os pases para cada registro de
cliente obtido, o iReport pode travar. Salve o relatrio principal e vamos agora para o
arquivo do subrelatrio. Caso queria, segue o XML do relatrio principal.
LocacoesPorClientes.jrxml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <jasperReport
xmlns="http://jasperreports.sourceforge.net/jasperreports"

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreport
http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
name="report name" pageWidth="595" pageHeight="842" columnWidth="535"
5 leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">

4s

<property name="ireport.zoom" value="1.0"/>

<property name="ireport.x" value="0"/>

<property name="ireport.y" value="0"/>

<parameter name="nomeCliente" class="java.lang.String"/>

1
0
1
1

<parameter name="nomeUsuario" class="java.lang.String"/>


<parameter
name="SUBREPORT_DIR"
isForPrompting="false">

class="java.lang.String"

<defaultValueExpression><![CDATA["C:\\Users\\David\\Documents
\\Blog\\tutoriais\\TutorialRelatorios\\relatorios\\"]]></defaultValue
1 Expression>

</parameter>

1
3

<queryString>
<![CDATA[SELECT

1
4

c.customer_id idCliente,
c.first_name nome,

1
5

c.last_name sobrenome,

1
6

c.email email,

1
7

a.phone telefone,

a.address endereco,

ci.city nomeCidade,

1
8

co.country nomePais

1
9 FROM
2
0

customer c,

2
1

city ci,

address a,

country co

2
2
2
3

WHERE
/* junes */

2
4

c.address_id = a.address_id AND

2
5

ci.country_id = co.country_id AND

2
6

/* restries */

a.city_id = ci.city_id AND

2
7

c.first_name LIKE $P{nomeCliente}

2
ORDER BY c.first_name;]]>
8
</queryString>

2
9
3
0

<field name="idCliente" class="java.lang.Integer"/>


<field name="nome" class="java.lang.String"/>
<field name="sobrenome" class="java.lang.String"/>

3
1

<field name="email" class="java.lang.String"/>

3
2

<field name="telefone" class="java.lang.String"/>

3
3

<field name="nomePais" class="java.lang.String"/>

3
4
3
5
3
6
3
7

<field name="endereco" class="java.lang.String"/>

<field name="nomeCidade" class="java.lang.String"/>

<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="75" splitType="Stretch">
<staticText>
<reportElement x="0" y="18" width="555" height="40"/>
<textElement

textAlignment="Center"

3 verticalAlignment="Middle">
8

<font size="25" isBold="true"/>

3
9

</textElement>
<text><![CDATA[Locaes por Clientes]]></text>

4
0
4
1
4
2
4
3

</staticText>
<line>
<reportElement x="0" y="1" width="555" height="1"/>
</line>
<line>
<reportElement x="0" y="74" width="555" height="1"/>

4
4
4
5
4
6
4
7

</line>
</band>
</title>
<pageHeader>
<band height="21" splitType="Stretch">
<staticText>
<reportElement x="-1" y="0" width="51" height="20"/>

<textElement
4
verticalAlignment="Middle">
8

4
9
5
0
5
1
5
2

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[Usurio:]]></text>
</staticText>
<textField>
<reportElement x="53" y="0" width="150" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression

5 class="java.lang.String"><![CDATA[$P{nomeUsuario}]]></textFieldExpres
3 sion>
5
4
5
5

</textField>
<staticText>
<reportElement x="360" y="0" width="68" height="20"/>
<textElement

textAlignment="Left"

5 verticalAlignment="Middle">
6
<font isBold="true"/>
5
7
5
8

</textElement>
<text><![CDATA[Gerado em:]]></text>
</staticText>
<textField

pattern="dd/MM/yyyy&apos;,

5 HH:mm&apos;hs&apos;">
9

s&apos;

<reportElement x="433" y="0" width="122" height="20"/>

6
0

<textElement verticalAlignment="Middle"/>
<textFieldExpression

6 class="java.util.Date"><![CDATA[new Date()]]></textFieldExpression>
1
</textField>

6
2
6
3
6
4
6
5
6
6
6
7
6
8
6
9

</band>
</pageHeader>
<detail>
<band height="175" splitType="Stretch">
<staticText>
<reportElement x="0" y="3" width="50" height="20"/>
<textElement
verticalAlignment="Middle">

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[Nome:]]></text>
</staticText>
<textField>
<reportElement x="0" y="23" width="99" height="20"/>
<textElement verticalAlignment="Middle"/>

7
0
7
1

<textFieldExpression
class="java.lang.String"><![CDATA[$F{nome}]]></textFieldExpression>
</textField>
<staticText>

7
2

<reportElement x="103" y="3" width="70" height="20"/>


<textElement

7
verticalAlignment="Middle">
3

textAlignment="Left"

<font isBold="true"/>

7
4
7
5
7
6
7
7

</textElement>
<text><![CDATA[Sobrenome:]]></text>
</staticText>
<textField>
<reportElement x="103" y="23" width="136" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression

7 class="java.lang.String"><![CDATA[$F{sobrenome}]]></textFieldExpressi
8 on>
7
9
8
0
8
1
8
2
8
3

</textField>
<staticText>
<reportElement x="242" y="3" width="70" height="20"/>
<textElement
verticalAlignment="Middle">

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[E-mail:]]></text>
</staticText>
<textField>

8
4
8
5
8
6
8
7

<reportElement x="242" y="23" width="228" height="20"/>


<textElement verticalAlignment="Middle"/>
<textFieldExpression
class="java.lang.String"><![CDATA[$F{email}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="0" y="47" width="59" height="20"/>

<textElement
8
verticalAlignment="Middle">
8

8
9
9
0
9
1
9
2

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[Endereo:]]></text>
</staticText>
<textField>
<reportElement x="62" y="47" width="177" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression

9 class="java.lang.String"><![CDATA[$F{endereco}]]></textFieldExpressio
3 n>
9
4

</textField>
<staticText>

9
5
9
6
9
7
9
8
9
9

<reportElement x="473" y="3" width="82" height="20"/>


<textElement verticalAlignment="Middle">
<font isBold="true"/>
</textElement>
<text><![CDATA[Telefone:]]></text>
</staticText>
<textField>
<reportElement x="473" y="23" width="82" height="20"/>
<textElement verticalAlignment="Middle"/>

1
<textFieldExpression
class="java.lang.String"><![CDATA[$F{telefone}]]></textFieldExpressio
0
0 n>
1
0
1

</textField>
<staticText>
<reportElement x="242" y="47" width="42" height="20"/>

1
<textElement
0 verticalAlignment="Middle">
2

textAlignment="Left"

<font isBold="true"/>

1
0
3
1
0
4

</textElement>
<text><![CDATA[Cidade:]]></text>
</staticText>
<textField>
<reportElement x="287" y="47" width="106" height="20"/>

1
0
5

<textElement verticalAlignment="Middle"/>

<textFieldExpression
class="java.lang.String"><![CDATA[$F{nomeCidade}]]></textFieldExpress
1 ion>

0
6
1
0
7

</textField>
<staticText>
<reportElement x="397" y="47" width="31" height="20"/>

<textElement
verticalAlignment="Middle">
1

<font isBold="true"/>

textAlignment="Left"

</textElement>

1
0
9

<text><![CDATA[Pas:]]></text>
</staticText>
<textField>

1
1
0

<reportElement x="433" y="47" width="122" height="20"/>


<textElement verticalAlignment="Middle"/>

<textFieldExpression
1
class="java.lang.String"><![CDATA[$F{nomePais}]]></textFieldExpressio
1
n>
1
</textField>

1
1
2

<line>
<reportElement x="0" y="1" width="555" height="1"/>

1
1
3

</line>
<subreport>
<reportElement x="7" y="71" width="544" height="100"/>

1
1
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]
4 ]></connectionExpression>
<subreportExpression
1
class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR}
1
"LocacoesPorClientes_Locacoes.jasper"]]></subreportExpression>
5

</subreport>

1
1
6
1
1
7
1
1
8

</band>
</detail>
<pageFooter>
<band height="22" splitType="Stretch">
<textField>
<reportElement x="455" y="2" width="100" height="20"/>
<textElement
verticalAlignment="Middle"/>

textAlignment="Right"

1
1
<textFieldExpression
9 class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpre
ssion>

1
2

</textField>

0
1
2
1

<line>
<reportElement x="0" y="1" width="555" height="1"/>
</line>
</band>

1
</pageFooter>
2
2 </jasperReport>
1
2
3
1
2
4
1
2
5
1
2
6
1
2
7
1
2
8
1
2
9
1
3
0
1
3
1
1
3

2
1
3
3
1
3
4
1
3
5
1
3
6
1
3
7
1
3
8
1
3
9
1
4
0
1
4
1
1
4
2
1
4
3
1
4

4
1
4
5
1
4
6
1
4
7
1
4
8
1
4
9
1
5
0
1
5
1
1
5
2
1
5
3
1
5
4
1
5
5
1
5

6
1
5
7
1
5
8
1
5
9
1
6
0
1
6
1
1
6
2
1
6
3
1
6
4
1
6
5
1
6
6
1
6
7
1
6

8
1
6
9
1
7
0
1
7
1
1
7
2
1
7
3
1
7
4
1
7
5
1
7
6
1
7
7
1
7
8
1
7
9
1
8

0
1
8
1
1
8
2
1
8
3
1
8
4
1
8
5
1
8
6
1
8
7
1
8
8
1
8
9
1
9
0
1
9
1
1
9

2
1
9
3
1
9
4
1
9
5
1
9
6
1
9
7
1
9
8
1
9
9
2
0
0
2
0
1
2
0
2
2
0
3

A primeira coisa que vamos fazer no arquivo do subrelatrio excluir todas as bandas,
exceto a Detail e a Column Header. Vamos agora criar um parmetro chamado

idCliente, que vai ser usado na nossa query para que possamos obter os filmes de um
determinado cliente. O tipo deve deve ser Integer. Vamos agora editar a query do
relatrio, onde vamos obter o nome e o ano do filme alugado, alm da data de
devoluo, sendo que iremos mostrar apenas os filmes que j foram alugados, ou seja,
com data de devoluo diferente de NULL. Teremos que fazer junes em algumas
tabelas para podermos obter os filmes alugados por um determinado cliente. A query
vai ficar assim:
1
2

SELECT
f.title titulo,

f.release_year anoLancamento,

4
r.return_date dataDevolucao

5
6

FROM

customer c,

rental r,

inventory i,

10

film f

11
12WHERE
13
14
15

/* junes */
r.customer_id = c.customer_id AND
r.inventory_id = i.inventory_id AND
i.film_id = f.film_id AND

16
17
/* restries */

18
19

c.customer_id LIKE $P{idCliente} AND


r.return_date IS NOT NULL

20
21ORDER BY r.return_date, f.title;
22

Ao clicar em OK, o iReport vai gerar os campos para podermos utilizar no subrelatrio.
Organize ento os campos da mesma forma que mostrado na Figura abaixo.

Layout do subrelatrio

Note que diminui a largura da pgina para 6,5 polegadas (6.5 inches). Para fazer isso, no
Report Inspector, clique com o boto direito no n raiz (deve estar com o nome do
arquivo de relatrio) e v em Page Format (primeira opo) e altere a largura (Width)
para 6.5 polegadas e clique em OK. Segue o cdigo XML do subrelatrio.
LocacoesPorClientes_Locacoes.jrxml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <jasperReport
xmlns="http://jasperreports.sourceforge.net/jasperreports"

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreport
http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
name="LocacoesPorClientes_Locacoes" language="groovy" pageWidth="468"
5 pageHeight="802" columnWidth="468" leftMargin="0" rightMargin="0"
topMargin="0" bottomMargin="0">

4s

6
<property name="ireport.zoom" value="1.0"/>

7
8

<property name="ireport.x" value="0"/>


<property name="ireport.y" value="0"/>

<parameter name="idCliente" class="java.lang.Integer"/>

1
0

<queryString>

1
1

<![CDATA[SELECT
f.title titulo,
f.release_year anoLancamento,

1
2

r.return_date dataDevolucao

1
3
1
4

FROM
customer c,
rental r,

1
5
1
6

inventory i,
film f

1 WHERE
7

/* junes */

1
8

r.customer_id = c.customer_id AND


r.inventory_id = i.inventory_id AND

1
9
2
0
2
1

i.film_id = f.film_id AND

/* restries */
c.customer_id LIKE $P{idCliente} AND
r.return_date IS NOT NULL

2
2
2
3

ORDER BY r.return_date, f.title;]]>


</queryString>

2
4

<field name="titulo" class="java.lang.String"/>

2
5

<field name="dataDevolucao" class="java.sql.Timestamp"/>

2
6

<field name="anoLancamento" class="java.sql.Date"/>

<background>
<band splitType="Stretch"/>
</background>

2
7
2
8
2
9

<columnHeader>
<band height="25">
<staticText>
<reportElement x="0" y="0" width="100" height="20"/>
<textElement

textAlignment="Center"

3 verticalAlignment="Middle">
0

<font isBold="true"/>

3
1

</textElement>
<text><![CDATA[Devolvido em]]></text>

3
2

</staticText>
<staticText>

3
3

<reportElement x="103" y="0" width="47" height="20"/>

3
4

<textElement verticalAlignment="Middle">

3
5

</textElement>

<font isBold="true"/>

<text><![CDATA[Ttulo]]></text>

3
6

</staticText>
<staticText>

3
7

<reportElement x="326" y="0" width="117" height="20"/>


<textElement verticalAlignment="Middle">

3
8

<font isBold="true"/>
</textElement>

3
9

<text><![CDATA[Ano de Lanamento]]></text>

4
0

</staticText>
<line>

4
1
4
2
4
3
4
4
4
5

<reportElement x="0" y="24" width="468" height="1"/>


</line>
</band>
</columnHeader>
<detail>
<band height="21" splitType="Stretch">
<textField pattern="dd/MM/yyyy">
<reportElement x="0" y="1" width="100" height="20"/>
<textElement

4 verticalAlignment="Middle"/>
6

<textFieldExpression

textAlignment="Center"

4 class="java.sql.Timestamp"><![CDATA[$F{dataDevolucao}]]></textFieldEx
7 pression>
4
8

</textField>
<textField>
<reportElement x="103" y="1" width="219" height="20"/>

4
9

<textElement verticalAlignment="Middle"/>

5
<textFieldExpression
0 class="java.lang.String"><![CDATA[$F{titulo}]]></textFieldExpression>
5
1

</textField>
<textField pattern="yyyy">

5
2

<reportElement x="326" y="1" width="117" height="20"/>


<textElement verticalAlignment="Middle"/>

5
3
5
4
5
5

<textFieldExpression
class="java.util.Date"><![CDATA[$F{anoLancamento}]]></textFieldExpres
sion>
</textField>
</band>
</detail>

5 </jasperReport>
6
5
7
5
8
5
9
6
0
6
1
6
2
6
3

6
4
6
5
6
6
6
7
6
8
6
9
7
0
7
1
7
2
7
3
7
4
7
5
7
6
7
7
7
8
7
9
8
0

8
1
8
2
8
3
8
4

D um preview no subreport, inserindo o valor 1 (sem as aspas) para o parmetro


idCliente. O preview deve ser parecido com o mostrado na Figura abaixo.

Preview do subrelatrio

Engraado notar que tem filmes que foram alugados pelo Cliente 1 antes de terem
sido lanados :D Enfim, estamos quase l. Falta agora ns fazermos os dois relatrios
funcionarem juntos. Lembram que falei que os parmetros do subrelatrio teriam de ser

enviados pelo relatrio principal? No nosso caso, o nosso subrelatrio espera pelo
parmetro idCliente ($P{idCliente}) para executar sua query. Ento precisamos fazer
com que o relatrio principal passe este valor, que est sendo guardado do campo
idCliente ($F{idCliente}) que obtido na query do relatrio principal.
Para isso, v no relatrio principal e selecione a caixa que vai conter o subrelatrio. Ao
selecion-la, procure pela propriedade Parameters no painel de propriedades. O valor
vai estar definido como No parameter defined. Clique no pequeno boto a direita e a
janela mostrada na Figura abaixo vai ser exibida.

Configurao de parmetros

Esta janela utilizada para criar um parmetro de passagem (eu que inventei esse nome
de parmetro de passagem), que deve ter o mesmo nome do parmetro esperado pelo
subrelatrio. Os parmetros de passagem ficam na coluna destacada em roxo da tabela.
O valor desse parmetro gerado pela expresso que for definida (coluna destacada em
verde). Para criar o novo parmetro de passagem, clique no boto Add. Ao clicar no
boto, a janela mostrada na Figura abaixo mostrada.

Janela para adicionar parmetros de passagem

Preencha o campo Subreport parameter name com o valor idCliente (nome do


parmetro do subrelatrio) e preencha o campo Value expression com o valor
$F{idCliente}, ou seja, o campo idCliente da query do relatrio principal e clique em
OK. Veja a Figura abaixo.

Criando novo parmetro de passagem

Note que voc pode usar o editor de expresses (Expression editor) clicando no boto
destacado em laranja. Entendeu o que fizemos? Amarramos o parmetro idCliente do
subrelatrio com o valor que vai ser inserido no campo idCliente ($F{idCliente}), ou
seja, a cada vez que o subrelatrio for chamado (para cada cliente) o valor do parmetro
idCliente vai ser configurado com o valor do campo idCliente. Note que o valor do
parmetro do subrelatrio tem que ser do mesmo tipo que o valor gerado pela expresso
de valor (value expression). nesta mesma janela que voc vai amarrar todos os
parmetros do subrelatrio com valores gerados no relatrio ou passados para ele. Por
exemplo, o subrelatrio tem um parmetro chamado paramSub1 e o valor deste
parmetro passado ao relatrio principal no parmetro chamado paramPrin1. Ento
voc teria que amarrar paramSub1 (coluna name, em verde) com a expresso
$P{paramPrin1} (coluna expression, em roxo) entendeu? como se estivssemos
chamando um mtodo, passando parmetros para ele. Segue ento o cdigo XML do
relatrio principal at o momento.
LocacoesPorClientes.jrxml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <jasperReport

xmlns="http://jasperreports.sourceforge.net/jasperreports"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreport

4s

http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
name="report name" pageWidth="595" pageHeight="842" columnWidth="535"
5 leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="1.0"/>

<property name="ireport.x" value="0"/>

<property name="ireport.y" value="0"/>

<parameter name="nomeCliente" class="java.lang.String"/>

9
<parameter name="nomeUsuario" class="java.lang.String"/>

1
0

<parameter
name="SUBREPORT_DIR"
isForPrompting="false">

class="java.lang.String"

1
<defaultValueExpression><![CDATA["C:\\Users\\David\\Documents
1 \\Blog\\tutoriais\\TutorialRelatorios\\relatorios\\"]]></defaultValue
1
2

Expression>
</parameter>

1
3

<queryString>

1
4

c.customer_id idCliente,

<![CDATA[SELECT

c.first_name nome,

1
5

c.last_name sobrenome,
c.email email,

1
6

a.address endereco,
a.phone telefone,

1
7

ci.city nomeCidade,
co.country nomePais

1
8
1
FROM
9

customer c,

2
0
2
1
2
2
2

address a,
city ci,
country co

WHERE

/* junes */

2
4

c.address_id = a.address_id AND

2
5

ci.country_id = co.country_id AND

2
6
2
7

a.city_id = ci.city_id AND

/* restries */
c.first_name LIKE $P{nomeCliente}

2 ORDER BY c.first_name;]]>
8
</queryString>

2
9

<field name="idCliente" class="java.lang.Integer"/>

3
0

<field name="sobrenome" class="java.lang.String"/>

3
1

<field name="nome" class="java.lang.String"/>

<field name="email" class="java.lang.String"/>


<field name="endereco" class="java.lang.String"/>

3
2

<field name="telefone" class="java.lang.String"/>

3
3

<field name="nomePais" class="java.lang.String"/>

3
4

<field name="nomeCidade" class="java.lang.String"/>

<background>
<band splitType="Stretch"/>
</background>

3
5
3
6
3
7
3
8
3
9
4

<title>
<band height="75" splitType="Stretch">
<staticText>
<reportElement x="0" y="18" width="555" height="40"/>
<textElement
verticalAlignment="Middle">

textAlignment="Center"

<font size="25" isBold="true"/>


</textElement>
<text><![CDATA[Locaes por Clientes]]></text>

</staticText>

4
1

<line>

4
2

</line>

<reportElement x="0" y="1" width="555" height="1"/>

<line>

4
3

<reportElement x="0" y="74" width="555" height="1"/>


</line>

4
4
4
5
4
6
4
7

</band>
</title>
<pageHeader>
<band height="21" splitType="Stretch">
<staticText>
<reportElement x="-1" y="0" width="51" height="20"/>

<textElement
verticalAlignment="Middle">
4

8
4
9

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[Usurio:]]></text>

5
0
5
1
5
2

</staticText>
<textField>
<reportElement x="53" y="0" width="150" height="20"/>
<textElement verticalAlignment="Middle"/>

<textFieldExpression
class="java.lang.String"><![CDATA[$P{nomeUsuario}]]></textFieldExpres
5 sion>

3
</textField>

5
4
5
5
5
6
5

<staticText>
<reportElement x="360" y="0" width="68" height="20"/>
<textElement
verticalAlignment="Middle">
<font isBold="true"/>
</textElement>

textAlignment="Left"

<text><![CDATA[Gerado em:]]></text>

7
5
8
5
9
6
0
6
1
6
2
6
3
6
4

</staticText>
<textField
HH:mm&apos;hs&apos;">

pattern="dd/MM/yyyy&apos;,

s&apos;

<reportElement x="433" y="0" width="122" height="20"/>


<textElement verticalAlignment="Middle"/>
<textFieldExpression
class="java.util.Date"><![CDATA[new Date()]]></textFieldExpression>
</textField>
</band>
</pageHeader>
<detail>
<band height="175" splitType="Stretch">
<staticText>
<reportElement x="0" y="3" width="50" height="20"/>

6
5
6
6

<textElement
verticalAlignment="Middle">

textAlignment="Left"

<font isBold="true"/>
</textElement>

6
7
6
8
6
9

<text><![CDATA[Nome:]]></text>
</staticText>
<textField>
<reportElement x="0" y="23" width="99" height="20"/>
<textElement verticalAlignment="Middle"/>

7
<textFieldExpression
0 class="java.lang.String"><![CDATA[$F{nome}]]></textFieldExpression>
7
1
7
2

</textField>
<staticText>
<reportElement x="103" y="3" width="70" height="20"/>
<textElement

7 verticalAlignment="Middle">
3

<font isBold="true"/>

textAlignment="Left"

</textElement>

7
5

<text><![CDATA[Sobrenome:]]></text>

7
6
7
7

</staticText>
<textField>
<reportElement x="103" y="23" width="136" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression

7 class="java.lang.String"><![CDATA[$F{sobrenome}]]></textFieldExpressi
8 on>
7
9
8
0

</textField>
<staticText>
<reportElement x="242" y="3" width="70" height="20"/>

<textElement
8 verticalAlignment="Middle">

1
8
2
8
3

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[E-mail:]]></text>
</staticText>
<textField>

8
4
8
5
8
6
8
7

<reportElement x="242" y="23" width="228" height="20"/>


<textElement verticalAlignment="Middle"/>
<textFieldExpression
class="java.lang.String"><![CDATA[$F{email}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="0" y="47" width="59" height="20"/>

<textElement
8
verticalAlignment="Middle">
8

8
9
9
0
9

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[Endereo:]]></text>
</staticText>

<textField>

<reportElement x="62" y="47" width="177" height="20"/>

9
2

<textElement verticalAlignment="Middle"/>

9
<textFieldExpression
3 class="java.lang.String"><![CDATA[$F{endereco}]]></textFieldExpressio
n>

9
4

</textField>
<staticText>

9
5

<reportElement x="473" y="3" width="82" height="20"/>

9
6

<textElement verticalAlignment="Middle">

9
7

</textElement>

<font isBold="true"/>

<text><![CDATA[Telefone:]]></text>

9
8

</staticText>
<textField>

9
9

<reportElement x="473" y="23" width="82" height="20"/>


<textElement verticalAlignment="Middle"/>

1
0
<textFieldExpression
class="java.lang.String"><![CDATA[$F{telefone}]]></textFieldExpressio
0
n>

1
0
1

</textField>
<staticText>

<reportElement x="242" y="47" width="42" height="20"/>


1
0
<textElement
textAlignment="Left"
2 verticalAlignment="Middle">

1
0
3
1
0
4
1
0
5

<font isBold="true"/>
</textElement>
<text><![CDATA[Cidade:]]></text>
</staticText>
<textField>
<reportElement x="287" y="47" width="106" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression

1 class="java.lang.String"><![CDATA[$F{nomeCidade}]]></textFieldExpress
0 ion>
6
</textField>
1
0
7

<staticText>
<reportElement x="397" y="47" width="31" height="20"/>
<textElement

1 verticalAlignment="Middle">
0
<font isBold="true"/>
8

textAlignment="Left"

</textElement>

1
0
9

<text><![CDATA[Pas:]]></text>
</staticText>

1
1
0

<textField>
<reportElement x="433" y="47" width="122" height="20"/>

<textElement verticalAlignment="Middle"/>
1
1
<textFieldExpression
1 class="java.lang.String"><![CDATA[$F{nomePais}]]></textFieldExpressio
n>

1
1
2
1
1
3
1
1
4

</textField>
<line>
<reportElement x="0" y="1" width="555" height="1"/>
</line>
<subreport>
<reportElement x="7" y="71" width="544" height="100"/>
<subreportParameter name="idCliente">

1
<subreportParameterExpression><![CDATA[$F{idClien
1 te}]]></subreportParameterExpression>
5
</subreportParameter>

1
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]
1 ]></connectionExpression>
6
<subreportExpression
1 class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR}
1 "LocacoesPorClientes_Locacoes.jasper"]]></subreportExpression>

7
1

</subreport>

1
8
1
1
9

</band>
</detail>
<pageFooter>
<band height="22" splitType="Stretch">
<textField>

1
2
0

<reportElement x="455" y="2" width="100" height="20"/>

<textElement
verticalAlignment="Middle"/>
1

textAlignment="Right"

2
<textFieldExpression
1 class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpre
ssion>

1
2
2
1
2
3
1
2
4
1
2
5
1
2
6
1
2
7
1
2
8
1
2
9
1
3

</textField>
<line>
<reportElement x="0" y="1" width="555" height="1"/>
</line>
</band>
</pageFooter>
</jasperReport>

0
1
3
1
1
3
2
1
3
3
1
3
4
1
3
5
1
3
6
1
3
7
1
3
8
1
3
9
1
4
0
1
4
1
1
4

2
1
4
3
1
4
4
1
4
5
1
4
6
1
4
7
1
4
8
1
4
9
1
5
0
1
5
1
1
5
2
1
5
3
1
5

4
1
5
5
1
5
6
1
5
7
1
5
8
1
5
9
1
6
0
1
6
1
1
6
2
1
6
3
1
6
4
1
6
5
1
6

6
1
6
7
1
6
8
1
6
9
1
7
0
1
7
1
1
7
2
1
7
3
1
7
4
1
7
5
1
7
6
1
7
7
1
7

8
1
7
9
1
8
0
1
8
1
1
8
2
1
8
3
1
8
4
1
8
5
1
8
6
1
8
7
1
8
8
1
8
9
1
9

0
1
9
1
1
9
2
1
9
3
1
9
4
1
9
5
1
9
6
1
9
7
1
9
8
1
9
9
2
0
0
2
0
1
2
0

2
2
0
3
2
0
4
2
0
5
2
0
6

Teste o relatrio e veja o que acontece. Voc vai perceber que para cada cliente ser
gerado uma lista de filmes. Agora que est tudo pronto, organize o layout do
subrelatrio e personalize da forma que achar melhor. Eu coloquei a largura com 7,694
polegadas e expandi a linha para ocupar toda a largura. Note que se voc mudar alguma
coisa no subrelatrio, vc precisar compilar apenas ele. Agora, para finalizar, vamos
chamar este relatrio a partir do nosso programa em Java, mas para isso ainda temos
que fazer algumas pequenas modificaes no arquivo de relatrio principal.
Para entender o que vamos fazer, abra o arquivo LocacoesPorClientes.jrxml e selecione
a caixa do subrelatrio. Nas propriedades procure pela propriedade Subreport
Expression. Essa expresso que responsvel em fazer o subrelatrio ser carregado, ou
seja, ela que define para o relatrio principal a localizao do subrelatrio. Por padro
na verdade, pq definimos quando usamos o assistente de subrelatrios ela vai conter
o valor $P{SUBREPORT_DIR} + LocacoesPorClientes_Locacoes.jasper, ou seja, o
caminho do subrelatrio formado pelo valor do parmetro SUBREPORT_DIR
concatenado com o nome do arquivo de Subrelatrio. O problema que o parmetro
SUBREPORT_DIR est configurado com um valor fixo, que corresponde ao caminho
absoluto do relatrio e isso no bom O que vamos fazer ento fazer com que tudo
execute corretamente tanto no projeto, quanto no programa compilado e empacotado.
Primeiro, no Report Inspector, procure pelo parmetro SUBREPORT_DIR. Ao
selecion-lo, verifique a propriedade Default Value Expression. Ela vai estar definida
como o caminho absoluto do diretrio onde est o subrelatrio. Vamos mudar esse valor
para / (com as aspas), ou seja, uma String que contm uma barra, que vai indicar a
raiz do projeto. O tipo da classe do parmetro ainda String. Ok, aqui est pronto.
Agora selecione novamente a caixa do subrelatrio. Na propriedade Subreport
expression entre com o seguinte cdigo.
getClass().getResource(
$P{SUBREPORT_DIR}
"LocacoesPorClientes_Locacoes.jasper" )

Note que o ponto e vrgula da instruo no colocado. Essa linha de cdigo vai
retornar um objeto URL que aponta para o arquivo do subrelatrio
(/LocacoesPorClientes_Locacoes.jasper), sendo ento carregado corretamente tanto
no projeto, quanto no .jar. Note que poderamos fixar esse valor sem precisar usar o
parmetro, mas caso haja a necessidade de mudar os diretrios dos subrelatrios, essa
abordagem facilita o trabalho, tendo apenas que mudar o valor padro do parmetro.
Como a expresso vai retornar um objeto URL, ainda nas propriedades da caixa do
subrelatrio, mude a Expression Class (logo abaixo da Subreport Expression) para
java.net.URL.
Feito isso, salve o relatrio e d um preview. Na aba iReport output vai ser acusado um
warning, dizendo que no possvel encontrar o relatrio, no entando o relatrio vai ser
renderizado direitinho. Agora no precisamos mais nos preocupar, pois tanto no
iReport, quanto no .jar que for ser gerado do projeto, o relatrio vai abrir corretamente
com o subrelatrio.
O cdigo do mtodo abrirRelatorioClientes() da classe Main foi alterado para:
1 public void abrirRelatorioClientes() {
2
3

InputStream
inputStream
"/LocacoesPorClientes.jasper" );

getClass().getResourceAsStream(

4
5

Map<String, Object> parametros = new HashMap<String, Object>();

parametros.put( "nomeCliente", "F%" );

7
8

try {

9
10

ReportUtils.openReport(
inputStream, parametros,

"Locaes

por

11
ConnectionFactory.getSakilaConnection() );

12
13

} catch ( SQLException exc ) {

14
15

exc.printStackTrace();
} catch ( JRException exc ) {

16
17

exc.printStackTrace();
}

Clientes",

18
19}

O cdigo das verses finais tanto do arquivo de relatrio principal, quanto do


subrelatrio esto listadas a seguir.
LocacoesPorClientes.jrxml
1

<?xml version="1.0" encoding="UTF-8"?>


<jasperReport

2 xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

3 xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreport
s

http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"

4 name="report name" pageWidth="595" pageHeight="842" columnWidth="535"


5

leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">

<property name="ireport.zoom" value="1.0"/>


<property name="ireport.x" value="0"/>

7
<property name="ireport.y" value="0"/>

8
9

<parameter name="nomeCliente" class="java.lang.String"/>


<parameter name="nomeUsuario" class="java.lang.String"/>

1
<parameter
name="SUBREPORT_DIR"
0 isForPrompting="false">
1
1 on>
1
2
1
3
1
4

<defaultValueExpression><![CDATA["/"]]></defaultValueExpressi

</parameter>
<queryString>
<![CDATA[SELECT
c.customer_id idCliente,
c.first_name nome,
c.last_name sobrenome,

1
5
1
6
1
7

class="java.lang.String"

c.email email,
a.address endereco,
a.phone telefone,
ci.city nomeCidade,
co.country nomePais

1
8
1
9

FROM
customer c,
address a,

2
0
2
1

city ci,
country co

2 WHERE
2

/* junes */

2
3

c.address_id = a.address_id AND


a.city_id = ci.city_id AND

2
4
2
5
2
6

ci.country_id = co.country_id AND

/* restries */
c.first_name LIKE $P{nomeCliente}

2
ORDER BY c.first_name;]]>
7
2
8

</queryString>
<field name="idCliente" class="java.lang.Integer"/>

2
9

<field name="nome" class="java.lang.String"/>

3
0

<field name="email" class="java.lang.String"/>

3
1

<field name="sobrenome" class="java.lang.String"/>

<field name="endereco" class="java.lang.String"/>


<field name="telefone" class="java.lang.String"/>
<field name="nomeCidade" class="java.lang.String"/>

3
2
3
3
3
4

<field name="nomePais" class="java.lang.String"/>


<background>
<band splitType="Stretch"/>
</background>

3
5

<title>
<band height="75" splitType="Stretch">

3
6
3
7

<staticText>
<reportElement x="0" y="18" width="555" height="40"/>
<textElement
verticalAlignment="Middle">

3
8

textAlignment="Center"

<font size="25" isBold="true"/>


</textElement>

3
9

<text><![CDATA[Locaes por Clientes]]></text>


</staticText>

4
0

<line>
<reportElement x="0" y="1" width="555" height="1"/>

4
1

</line>

4
2

<line>
<reportElement x="0" y="74" width="555" height="1"/>

4
3

</line>
</band>

4
4
4
5
4
6

</title>
<pageHeader>
<band height="21" splitType="Stretch">
<staticText>
<reportElement x="-1" y="0" width="51" height="20"/>

4
<textElement
7 verticalAlignment="Middle">
4
8
4
9

textAlignment="Left"

<font isBold="true"/>
</textElement>
<text><![CDATA[Usurio:]]></text>
</staticText>

5
0
5
1

<textField>
<reportElement x="53" y="0" width="150" height="20"/>
<textElement verticalAlignment="Middle"/>

<textFieldExpression
5
2 class="java.lang.String"><![CDATA[$P{nomeUsuario}]]></textFieldExpres
sion>

5
3

</textField>
<staticText>

5
4

<reportElement x="360" y="0" width="68" height="20"/>


<textElement

textAlignment="Left"

5
verticalAlignment="Middle">
5

<font isBold="true"/>

5
6

</textElement>
<text><![CDATA[Gerado em:]]></text>

5
7

</staticText>

<textField
5
HH:mm&apos;hs&apos;">
8

pattern="dd/MM/yyyy&apos;,

s&apos;

<reportElement x="433" y="0" width="122" height="20"/>

5
9

<textElement verticalAlignment="Middle"/>

<textFieldExpression
6
0 class="java.util.Date"><![CDATA[new Date()]]></textFieldExpression>

6
1
6
2
6
3

</textField>
</band>
</pageHeader>
<detail>
<band height="196" splitType="Stretch">
<staticText>

6
4

<reportElement x="0" y="3" width="50" height="20"/>


<textElement

6
verticalAlignment="Middle">
5

textAlignment="Left"

<font isBold="true"/>

6
6
6
7
6
8

</textElement>
<text><![CDATA[Nome:]]></text>
</staticText>
<textField>
<reportElement x="0" y="23" width="99" height="20"/>

6
9
7
0

<textElement verticalAlignment="Middle"/>
<textFieldExpression
class="java.lang.String"><![CDATA[$F{nome}]]></textFieldExpression>
</textField>
<staticText>

7
1

<reportElement x="103" y="3" width="70" height="20"/>

7
<textElement
2 verticalAlignment="Middle">

textAlignment="Left"

<font isBold="true"/>

7
3

</textElement>

7
4

<text><![CDATA[Sobrenome:]]></text>
</staticText>

7
5

<textField>
<reportElement x="103" y="23" width="136" height="20"/>

7
6

<textElement verticalAlignment="Middle"/>

<textFieldExpression
7
class="java.lang.String"><![CDATA[$F{sobrenome}]]></textFieldExpressi
7
on>

7
8

</textField>
<staticText>

7
9

<reportElement x="242" y="3" width="70" height="20"/>


<textElement

8 verticalAlignment="Middle">
0

textAlignment="Left"

<font isBold="true"/>

8
1
8
2
8
3
8
4

</textElement>
<text><![CDATA[E-mail:]]></text>
</staticText>
<textField>
<reportElement x="242" y="23" width="228" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression

8 class="java.lang.String"><![CDATA[$F{email}]]></textFieldExpression>
5
</textField>

<staticText>

8
6

<reportElement x="0" y="47" width="59" height="20"/>

8
<textElement
7 verticalAlignment="Middle">

textAlignment="Left"

<font isBold="true"/>

8
8

</textElement>

8
9

<text><![CDATA[Endereo:]]></text>
</staticText>

9
0

<textField>
<reportElement x="62" y="47" width="177" height="20"/>

9
1

<textElement verticalAlignment="Middle"/>

<textFieldExpression
9
class="java.lang.String"><![CDATA[$F{endereco}]]></textFieldExpressio
2
n>

9
3

</textField>
<staticText>

9
4
9
5
9
6
9
7
9
8

<reportElement x="473" y="3" width="82" height="20"/>


<textElement verticalAlignment="Middle">
<font isBold="true"/>
</textElement>
<text><![CDATA[Telefone:]]></text>
</staticText>
<textField>
<reportElement x="473" y="23" width="82" height="20"/>
<textElement verticalAlignment="Middle"/>

9
9

<textFieldExpression
class="java.lang.String"><![CDATA[$F{telefone}]]></textFieldExpressio
1 n>

0
0

</textField>
<staticText>

1
0
1

<reportElement x="242" y="47" width="42" height="20"/>


<textElement
verticalAlignment="Middle">

textAlignment="Left"

1
0
2

<font isBold="true"/>
</textElement>
<text><![CDATA[Cidade:]]></text>

1
0
3
1
0
4

</staticText>
<textField>
<reportElement x="287" y="47" width="106" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression

1 class="java.lang.String"><![CDATA[$F{nomeCidade}]]></textFieldExpress
0 ion>
5
</textField>

1
0
6

<staticText>
<reportElement x="397" y="47" width="31" height="20"/>

<textElement
1
verticalAlignment="Middle">
0
7
<font isBold="true"/>

1
0
8

textAlignment="Left"

</textElement>
<text><![CDATA[Pas:]]></text>
</staticText>

1
0
9
1
1
0
1
1
1
1
1
2
1
1
3

<textField>
<reportElement x="433" y="47" width="122" height="20"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression
class="java.lang.String"><![CDATA[$F{nomePais}]]></textFieldExpressio
n>
</textField>
<line>
<reportElement x="0" y="1" width="555" height="1"/>
</line>
<subreport>
<reportElement x="0" y="96" width="555" height="100"/>
<subreportParameter name="idCliente">

<subreportParameterExpression><![CDATA[$F{idClien

1 te}]]></subreportParameterExpression>
4
</subreportParameter>

1
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]
1 ]></connectionExpression>
5

<subreportExpression
class="java.net.URL"><![CDATA[getClass().getResource(
1
$P{SUBREPORT_DIR}
+
"LocacoesPorClientes_Locacoes.jasper"
1
)]]></subreportExpression>

</subreport>

1
1
7

<staticText>
<reportElement x="0" y="72" width="555" height="20"/>

1
<textElement
1 verticalAlignment="Middle">
8

textAlignment="Center"

<font size="12" isBold="true"/>

1
1
9
1
2
0
1
2
1
1
2
2

</textElement>
<text><![CDATA[Filmes alugados]]></text>
</staticText>
<line>
<reportElement x="0" y="71" width="555" height="1"/>
</line>
<line>
<reportElement x="0" y="92" width="555" height="1"/>
</line>
</band>

1
2
3
1
2
4

</detail>
<pageFooter>
<band height="22" splitType="Stretch">
<textField>
<reportElement x="455" y="2" width="100" height="20"/>

1
<textElement
2
verticalAlignment="Middle"/>
5
<textFieldExpression

textAlignment="Right"

1 class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpre
2

6 ssion>
1
2
7
1
2
8

</textField>
<line>
<reportElement x="0" y="1" width="555" height="1"/>
</line>
</band>

</pageFooter>
1
2
</jasperReport>
9

1
3
0
1
3
1
1
3
2
1
3
3
1
3
4
1
3
5
1
3
6
1
3
7
1
3

8
1
3
9
1
4
0
1
4
1
1
4
2
1
4
3
1
4
4
1
4
5
1
4
6
1
4
7
1
4
8
1
4
9
1
5

0
1
5
1
1
5
2
1
5
3
1
5
4
1
5
5
1
5
6
1
5
7
1
5
8
1
5
9
1
6
0
1
6
1
1
6

2
1
6
3
1
6
4
1
6
5
1
6
6
1
6
7
1
6
8
1
6
9
1
7
0
1
7
1
1
7
2
1
7
3
1
7

4
1
7
5
1
7
6
1
7
7
1
7
8
1
7
9
1
8
0
1
8
1
1
8
2
1
8
3
1
8
4
1
8
5
1
8

6
1
8
7
1
8
8
1
8
9
1
9
0
1
9
1
1
9
2
1
9
3
1
9
4
1
9
5
1
9
6
1
9
7
1
9

8
1
9
9
2
0
0
2
0
1
2
0
2
2
0
3
2
0
4
2
0
5
2
0
6
2
0
7
2
0
8
2
0
9
2
1

0
2
1
1
2
1
2
2
1
3
2
1
4
2
1
5
2
1
6
2
1
7
2
1
8
2
1
9

LocacoesPorClientes_Locacoes.jrxml
1

<?xml version="1.0" encoding="UTF-8"?>


<jasperReport

2 xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

3 xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreport
s

http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"

4 name="LocacoesPorClientes_Locacoes" language="groovy" pageWidth="554"


pageHeight="802"

columnWidth="554"

leftMargin="0"

rightMargin="0"

5 topMargin="0" bottomMargin="0">
<property name="ireport.zoom" value="1.0"/>

<property name="ireport.x" value="0"/>

<property name="ireport.y" value="0"/>

<parameter name="idCliente" class="java.lang.Integer"/>

9
<queryString>

1
0

<![CDATA[SELECT
f.title titulo,

1
1

f.release_year anoLancamento,
r.return_date dataDevolucao

1
2
1 FROM
3

customer c,

1
4
1
5
1
6
1
7

rental r,
inventory i,
film f

WHERE
/* junes */
r.customer_id = c.customer_id AND

1
8
1
9

r.inventory_id = i.inventory_id AND


i.film_id = f.film_id AND

2
0

/* restries */

2
1

r.return_date IS NOT NULL

c.customer_id LIKE $P{idCliente} AND

2
2 ORDER BY r.return_date, f.title;]]>
2
3

</queryString>

2
4

<field name="titulo" class="java.lang.String"/>

2
5

<field name="dataDevolucao" class="java.sql.Timestamp"/>

2
6
2
7
2
8
2
9

<field name="anoLancamento" class="java.sql.Date"/>

<background>
<band splitType="Stretch"/>
</background>
<columnHeader>
<band height="25">
<staticText>
<reportElement x="0" y="0" width="100" height="20"/>

<textElement
verticalAlignment="Middle">
3

0
3
1
3
2

textAlignment="Center"

<font isBold="true"/>
</textElement>
<text><![CDATA[Devolvido em]]></text>
</staticText>
<staticText>

3
3
3
4
3
5
3
6

<reportElement x="103" y="0" width="47" height="20"/>


<textElement verticalAlignment="Middle">
<font isBold="true"/>
</textElement>
<text><![CDATA[Ttulo]]></text>
</staticText>
<staticText>

3
7
3
8
3
9
4
0

<reportElement x="326" y="0" width="117" height="20"/>


<textElement verticalAlignment="Middle">
<font isBold="true"/>
</textElement>
<text><![CDATA[Ano de Lanamento]]></text>
</staticText>

4
1

<line>

4
2

</line>

4
3
4
4

<reportElement x="0" y="24" width="554" height="1"/>

</band>
</columnHeader>
<detail>
<band height="21" splitType="Stretch">
<textField pattern="dd/MM/yyyy">

4
5

<reportElement x="0" y="1" width="100" height="20"/>

4
<textElement
verticalAlignment="Middle"/>
6

textAlignment="Center"

<textFieldExpression
4
class="java.sql.Timestamp"><![CDATA[$F{dataDevolucao}]]></textFieldEx
7
pression>

4
8

</textField>
<textField>

4
9
5
0
5
1
5
2

<reportElement x="103" y="1" width="219" height="20"/>


<textElement verticalAlignment="Middle"/>
<textFieldExpression
class="java.lang.String"><![CDATA[$F{titulo}]]></textFieldExpression>
</textField>
<textField pattern="yyyy">
<reportElement x="326" y="1" width="117" height="20"/>
<textElement verticalAlignment="Middle"/>

5
3

<textFieldExpression
class="java.util.Date"><![CDATA[$F{anoLancamento}]]></textFieldExpres
5
sion>

</textField>

5
5

</band>
</detail>

5
6 </jasperReport>
5
7

5
8
5
9
6
0
6
1
6
2
6
3
6
4
6
5
6
6
6
7
6
8
6
9
7
0
7
1
7
2
7
3
7
4

7
5
7
6
7
7
7
8
7
9
8
0
8
1
8
2
8
3
8
4

O preview da verso final do meu relatrio ficou assim:

Verso final do relatrio

Ento isso! Terminamos mais uma parte do tutorial! Espero que tenham gostado e que
tenha auxiliado quem ainda tinha dificuldade com os subrelatrios. O projeto finalizado
desta parte do tutorial pode ser obtido neste link. Na prxima parte do tutorial iremos
aprender a trabalhar com outros tipos de datasources alm das conexes que estamos
usando at agora.
Grande abrao a todos! At a prxima parte ;)
Parte 1 Parte 2 Parte 3 Parte 4 Parte 5

JasperReports: Trabalhando com Relatrios em Java


Parte 4 (Diferentes tipos de Fontes de Dados
Datasources)
Filed under: Java, Programao, Relatrios 15 Comentrios
11/11/2010

9 Votes

Parte 1 Parte 2 Parte 3 Parte 4 Parte 5


Ol a todos! Finalmente, depois de um bom tempo sem postar, vamos quarta parte do
tutorial sobre relatrios! Nesta parte iremos aprender a usar outros tipos de datasources
para obtermos os dados que sero apresentados nos nossos relatrios. Como de
costume, vou explicar como fazer para utilizar a funcionalidade, permitindo que vocs
consigam caminhar sozinhos posteriormente.
Nas trs partes anteriores, a nossa fonte de dados era uma conexo JDBC que era usada
para executar uma query SQL. A partir do resultado da query, o JasperReports
preenchia o relatrio para ns. Imagine agora a seguinte situao: Eu tenho uma lista de
objetos do tipo Cliente e quero exibir essa lista de clientes em um relatrio. Note que
eu j tenho a lista, que foi obtida de alguma forma, ou seja, usando um DAO, ou
executando uma query pelo Hibernate.
Para conseguir fazer isso, utilizamos outros tipos de datasources. Se voc est seguindo
o tutorial desde o incio, seu projeto do NetBeans deve estar preparado para iniciarmos.
Caso no esteja seguindo, faa o download do projeto clicando aqui. Abra o projeto, e
procure pela classe ReportUtils no pacote tutorialrelatorios.util. O cdigo dela deve
estar assim:
tutorialrelatorios.util.ReportUtils.java
1

package tutorialrelatorios.util;

2
3

import java.awt.BorderLayout;

import java.io.InputStream;

import java.sql.Connection;

import java.util.Map;

import javax.swing.JFrame;

import net.sf.jasperreports.engine.JRDataSource;

import net.sf.jasperreports.engine.JRException;

10
11

import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.swing.JRViewer;

12
13
/**

14
15

* Classe com mtodos utilitrios para executar e abrir relatrios.


*

16

* @author David Buzatto

17

*/

18 public class ReportUtils {


19
20
21
22

/**
* Abre um relatrio usando uma conexo como datasource.
*
* @param titulo Ttulo usado na janela do relatrio.

23
* @param inputStream InputStream que contm o relatrio.

24
25
26
27
28

* @param parametros Parmetros utilizados pelo relatrio.


* @param conexao Conexo utilizada para a execuo da query.
* @throws JRException Caso ocorra algum problema na execuo do
relatrio
*/
public static void openReport(

29
String titulo,

30

InputStream inputStream,

31

Map parametros,

32

Connection conexao ) throws JRException {

33
34

/*

35

*
relatrio,

36

Cria

um

JasperPrint,

que

verso

preenchida

do

* usando uma conexo.

37

*/

38

JasperPrint print = JasperFillManager.fillReport(

39

inputStream, parametros, conexao );

40
41

// abre o JasperPrint em um JFrame

42

viewReportFrame( titulo, print );

43
44

45
46

/**
* Abre um relatrio usando um datasource genrico.

47
*

48
49

* @param titulo Ttulo usado na janela do relatrio.


* @param inputStream InputStream que contm o relatrio.

50

* @param parametros Parmetros utilizados pelo relatrio.

51

* @param dataSource Datasource a ser utilizado pelo relatrio.

52
53
54

* @throws JRException Caso ocorra algum problema na execuo do


relatrio
*/
public static void openReport(

55

String titulo,

56

InputStream inputStream,

57

Map parametros,

58

JRDataSource dataSource ) throws JRException {

59
60

/*

61

*
relatrio,

Cria

um

JasperPrint,

que

verso

preenchida

do

62

* usando um datasource genrico.

63

*/
JasperPrint print = JasperFillManager.fillReport(

64

inputStream, parametros, dataSource );

65
66

// abre o JasperPrint em um JFrame

67
viewReportFrame( titulo, print );

68
69

70
71
72
73

/**
* Cria um JFrame para exibir o relatrio representado pelo
JasperPrint.
*

74
* @param titulo Ttulo do JFrame.

75
76
77
78

* @param print JasperPrint do relatrio.


*/
private static void viewReportFrame( String titulo, JasperPrint
print ) {

79
80

/*
* Cria um JRViewer para exibir o relatrio.

81
82
83

* Um JRViewer uma JPanel.


*/
JRViewer viewer = new JRViewer( print );

84
85

// cria o JFrame

86

JFrame frameRelatorio = new JFrame( titulo );

87
88

// adiciona o JRViewer no JFrame

frameRelatorio.add( viewer, BorderLayout.CENTER );

89
90

// configura o tamanho padro do JFrame

91

frameRelatorio.setSize( 500, 500 );

92
93

// maximiza o JFrame para ocupar a tela toda.

94

frameRelatorio.setExtendedState( JFrame.MAXIMIZED_BOTH );

95
96
// configura a operao padro quando o JFrame for fechado.

97

frameRelatorio.setDefaultCloseOperation(
JFrame.DISPOSE_ON_CLOSE
);
98

99
// exibe o JFrame

100

frameRelatorio.setVisible( true );

101
102
}

103
104
}

105
106
107
108
109

Note que nessa classe existem dois mtodos chamados openReport(). O primeiro
deles o que utilizamos at agora, que recebe uma String que vai ser usada como ttulo
do JFrame utilizado como container do relatrio, um InputStream que vai ser usado para
obtermos o arquivo .jasper, um Map que contm os parmetros passados para o relatrio
e, por fim, uma Connection para a base de dados que usamos na query do relatrio.
Note que o segundo mtodo openReport() tem praticamente a mesma assinatura do
primeiro, mudando apenas o ltimo parmetro, que nessa verso do mtodo um
JRDataSource. A implementao do mtodo igual ao outro, com a diferena de ser
passado o JRDataSource para o JasperFillManager.fillReport() ao invs da
Connection.

O JRDataSource uma interface que define o contrato que os datasources devem seguir
para que o JasperReports possa usar os dados contidos neles dentro do relatrio. A
documentao da interface JRDataSource pode ser vista clicando aqui. Ao analisar a
documentao, vocs vo ver que existem diversas implementaes da interface
JRDataSource. Ns vamos focar em duas:

JRBeanCollectionDataSource: Utilizada para usar colees como fonte de dados, ou


seja, qualquer classe que implemente ou interface que estenda a interface
java.util.Collection. Por exemplo, um ArrayList, que implementa a interface List que
por sua vez estende a interface Collection. A documentao deste tipo de datasource
pode ser vista clicando aqui;
JRBeanArrayCollectionDataSource: Utilizado para usar arrays de objetos como fonte
de dados. A documentao deste tipo de datasource pode ser vista clicando aqui.

Legal no ? Ento, alm da conexo JDBC, ns podemos utilizar vrios outros tipos de
datasources. Vou o primeiro deles, e depois a utilizao do segundo vai ficar como
exerccio. No vou explicar cada um dos tipos existentes, pois o funcionamento deles
sempre muito parecido. Se voc precisar de outro tipo de datasource, basta ler a
documentao.
A utilizao dos datasources no complicada, bastando voc criar um objeto do tipo
do datasource desejado e passar o parmetro que ele espera, entretanto precisamos
alterar uma configurao no iReport para indicar ao compilador onde esto as classes
que vamos utilizar para instanciar os objetos e enviar no datasource. Antes de fazer isso,
vamos criar uma classe no nosso projeto, sendo que essa classe ser utilizada como a
nossa entidade. Ns vamos instanciar objetos dessa classe manualmente, mas em um
caso real, esses objetos viro de algum outro lugar, como uma query do Hibernate como
eu j mencionei. Vamos l ento!
Clique com o boto direito no pacote tutorialrelatorios, escolha New -> Java Package.
Se esta opo no estiver sendo exibida, clique em Other, escolha a categoria Java e em
File Type escolha Java Package. Com o assistente aberto, insira
tutorialrelatorios.entidades (sem as aspas) em Package Name e clique em Finish. O
pacote ser criado. Clique com o boto direito neste pacote, escolha New -> Java Class.
Preencha o campo Class Name com Cliente (sem as aspas) e clique em Finish. A
classe ser gerada e ser aberta no editor. Crie os campos id (privado, Long), nome
(privado, String) e sobrenome (privado, String). Com os campos criados, gere os gets e
os sets. Segue o cdigo da classe Cliente.
tutorialrelatorios.entidades.Cliente.java
1 package tutorialrelatorios.entidades;
2
3 /**
4

* Representa um Cliente.

* @author David Buzatto

*/

public class Cliente {

9
10

private Long id;


private String nome;

11
private String sobrenome;

12
13

public Long getId() {

14
15

return id;
}

16
17

public void setId( Long id ) {


this.id = id;

18
19

20
21

public String getNome() {


return nome;

22
}

23
24
public void setNome( String nome ) {

25
26

this.nome = nome;
}

27
28

public String getSobrenome() {

29
30

return sobrenome;
}

31
32

public void setSobrenome( String sobrenome ) {

this.sobrenome = sobrenome;

33
34

35
}

36
37
38

Agora, antes de partirmos para o nosso relatrio, precisamos configurar o iReport para
enxergar as classes do nosso projeto, permitindo assim que possamos utilizar nossas
entidades no relatrio. Antes disso, d um build no projeto (boto direito no projeto,
Build, ou Clean and Build), para que o diretrio de build seja gerado, ou seja, o
diretrio que contm os arquivos compilados no nosso projeto. Com o build feito, entre
no menu Tools e v em Options. Clique no boto do iReport e procure pela guia
Classpath. Com a guia aberta, clique no boto Add Folder. Ao clicar no boto, ser
exibido um dilogo para voc procurar a pasta desejada. Ns precisamos encontrar a
pasta build/classes do nosso projeto. No meu caso, eu estou salvando o projeto em
C:\Users\David\Documents\Blog\tutoriais, ento o build/classes est localizado em
C:\Users\David\Documents\Blog\tutoriais\TutorialRelatorios\build\classes. Procure
ento pelo o seu build/classes, selecione o diretrio e clique em Open. O editor de
opes da IDE deve ficar assim:

Editando o Classpath do iReport


Com isso feito, o iReport vai conseguir enxergar as classes do nosso projeto, alm de
permitir que objetos de nossas classes possam ser utilizadas dentro do relatrio. Vamos
criar nosso relatrio ento? Clique ento com o boto direito no <default package> da
nossa pasta de definies de relatrios, escolha New -> Empty Report. Como j temos
um relatrio chamado Clientes (que usa uma query lembram?), vamos dar o nome nesse
relatrio de ClientesCollectionDS, pois vamos utilizar o datasource do tipo
JRBeanCollectionDataSource. Assim que clicar em Finish no assistente de criao de
relatrios, o arquivo ClientesCollectionDS.jrxml ser gerado e ser aberto no editor.
Para simplificar, remova todas as bandas, exceto a Title, a Column Header e a Detail.
Na banda Title crie um campo de texto esttico e defina o ttulo do relatrio. O meu
ficou assim:

Layout Inicial do Relatrio de Clientes usando Collection DS


Agora chegou a parte onde vamos obter os atributos da nossa entidade Cliente. Clique
no boto usado para editar a query do relatrio e acesse a guia JavaBean Datasource.
Note que no vamos criar uma query. Com a aba aberta, preencha o campo Class
name com tutorialrelatorios.entidades.Cliente (sem as aspas) e clique no boto Read
Attributes. Vo ser lidos 4 atributos: class, id, nome e sobrenome. Selecione todos,
exceto o class e clique em Add selected field(s). Ao fazer isso, os campos sero
inseridos na tabela de campos do editor. Veja a Figura abaixo.

Carregando Campos de Uma Classe


Perceba que voc precisa inserir o nome completo da classe (pacote + nome da classe)
para que o iReport encontre a classe e a possa utilizar no relatrio. Com isso feito,
clique em OK. Os campos sero criados no Report Inspector da mesma forma que
seriam criados caso estivssemos usando uma query tradicional. Agora que os campos
esto criados, basta vocs montarem o relatrio, arrastando os campos para a banda
Detail e editando o ttulo de cada um deles. O meu ficou assim:

Layout Final do Relatrio de Clientes usando Collection DS


Note que se vocs tentarem dar um Preview no relatrio, vocs sero avisados que o
relatrio no contm pginas, justamente porque no existem dados para serem
exibidos. possvel criar um datasource para ser usado no preview do relatrio, mas
isso eu vou deixar como exerccio para vocs caso vocs queiram descobrir como faz :).
Compilem o relatrio e vamos agora modificar o mtodo main da classe Main para
chamar o relatrio criado, passando os dados para o relatrio. Abra a classe Main do
projeto e copiem o mtodo abrirRelatorioClientes. Mudem o nome do mtodo copiado
para abrirRelatorioClientesDS. Agora, como exerccio antes de ver o cdigo pronto,
tentem chamar o novo relatrio, criando um JRBeanCollectionDataSource e passando
para o mtodo openReport. Conseguiram? Espero que sim! Segue o cdigo completo da
classe Main.
tutorialrelatorios.Main.java
1

package tutorialrelatorios;

2
3

import java.io.InputStream;
import java.sql.SQLException;

4
5
6

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

7 import java.util.Map;
8 import net.sf.jasperreports.engine.JRDataSource;
9

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

10

import tutorialrelatorios.entidades.Cliente;

11
import tutorialrelatorios.jdbc.ConnectionFactory;

12

import tutorialrelatorios.util.ReportUtils;

13
14

/**

15 * Ponto de entrada do projeto.


16 *
17 * @author David Buzatto
18 */
public class Main {

19
20
21

/**
* @param args the command line arguments

22
*/

23

public static void main(String[] args) {

24
25

new Main().abrirRelatorioClientesDS();
}

26
27

public void abrirRelatorioClientes() {

28
29

InputStream inputStream
"/LocacoesPorClientes.jasper" );

getClass().getResourceAsStream(

30
31
Map parametros = new HashMap();

32
33

parametros.put( "nomeCliente", "F%" );

try {

34
35

ReportUtils.openReport(
inputStream, parametros,

"Locaes

36
37

por

Clientes",

ConnectionFactory.getSakilaConnection() );

38
39

} catch ( SQLException exc ) {

40

exc.printStackTrace();
} catch ( JRException exc ) {

41

exc.printStackTrace();

42
}

43
44
45

46
public void abrirRelatorioClientesDS() {

47
48
InputStream

inputStream

getClass().getResourceAsStream(

49"/ClientesCollectionDS.jasper" );
50
51

Map parametros = new HashMap();

52
53
54

// criando os dados que sero passados ao datasource


List dados = new ArrayList();

55
56

for ( long i = 1; i <= 50; i++ ) {


Cliente c = new Cliente();

57
58
59
60

c.setId( i );
c.setNome( "Nome Cliente " + i );
c.setSobrenome( "Sobrenome Cliente " + i );
dados.add( c );

61
62

// criando o datasource com os dados criados

63

JRDataSource ds = new JRBeanCollectionDataSource( dados );

64
65

try {

66
67

//

passando

datasource

para

mtodo

de

criao

68exibio do relatrio
ReportUtils.openReport( "Clientes - Bean Collection Data
Source", inputStream, parametros,

69
70

ds );

71
72

} catch ( JRException exc ) {

73

exc.printStackTrace();

74

75
76

77
78}
79
80
81
82

Ao executar a classe Main, o relatrio ser exibido. O meu ficou assim:

Exibio Final do Relatrio Criado


Como
exerccio, reaproveitem
o mtodo criado para utilizar um
JRBeanArrayDataSource. Lembrem-se que um datasource deste tipo espera um array,
no uma coleo.
Com isso finalizamos a quarta parte do tutorial! O projeto com o estado atual do nosso
tutorial pode ser baixado clicando-se aqui. Na prxima parte do tuorial, iremos aprender
como utilizar os relatrios em pginas Web, finalizando ento o bsico que vocs
devem saber para poder trabalhar com relatrios. At mais! Grande abrao!
Parte 1 Parte 2 Parte 3 Parte 4 Parte 5

JasperReports: Trabalhando com Relatrios em Java


Parte 5 (Relatrios na Web)
Filed under: Java, Programao, Relatrios, Web 37 Comentrios
12/11/2010

10 Votes

Parte 1 Parte 2 Parte 3 Parte 4 Parte 5


Ol a todos! Nesta quinta e ltima parte do nosso tutorial, iremos aprender a como usar
os nossos relatrios em um projeto Web. Esse parte do tutorial vai ser rpida, pois j
temos praticamente tudo o que precisamos. Primeiro gostaria de pedir para quem no
est acompanhando o tutorial, que baixe o projeto finalizado na Parte 4 clicando aqui.
Iremos criar um novo projeto no NetBeans, s que agora do tipo Web e vamos
configur-lo com base no que j fizemos no nosso projeto original. Vamos l ento!
No NetBeans, v em File -> New Project. No assistente de criao de projetos, escolha
Java Web na lista de categorias e na lista de tipos de projetos, escolha Web
Application. Clique em Next. Em Project Name d o nome do projeto. Eu sugiro
TutorialRelatoriosWeb (sem as aspas). Em Project Location escolha onde o projeto
vai ser salvo. Eu vou deixar na mesma pasta do projeto original. Marque a opo Use
Dedicated Folder for Storing Libraries e deixe o valor padro (.\lib). Se quiser, marque
a opo Set as Main Project. Clique em Next.
No prximo passo, onde configurado o servidor que a aplicao vai ser executada, eu
vou deixar o Tomcat escolhido. Se vocs preferirem usar outro servidor, no tem
problema, basta selecion-lo na lista. Deixe desmarcada a opo Use dedicated library
folder for server JAR files. Em JavaEE version, deixe escolhida a verso padro,
pois no precisamos nos preocupar com isso no nosso projeto de testes. No meu caso,
ficou selecionado Java EE 5. Em Context Path deixe o valor sugerido. No meu caso,
/TutorialRelatoriosWeb. Como no vamos usar nenhum framework MVC, voc j
pode clicar em Next. Feito isso, o projeto ser criado e ser aberto no NetBeans.
Com o projeto criado, acesse suas propriedades clicando com boto direito na raiz do
projeto e escolhendo a opo Properties, que a ltima da lista. Em Categories
procure pelo item Run e selecione-o. Desmarque a opo Deploy on Save para
evitar que seja feito um deploy a cada vez que salvarmos algo do nosso projeto. J que
estamos aqui, vamos aproveitar para configurar as bibiliotecas. No vou colocar as
figuras desse processo, pois j foi explicado nas primeiras partes do tutorial.
Selecione o item Libraries na lista de categorias e clique no boto Add Library.
Primeiro vamos importar o driver do MySQL que vamos utilizar. Na janela que foi
aberta, clique no boto Import. Procure pela biblioteca MySQL JDBC Driver,
selecione-a e clique no boto Import Library. A biblioteca vai ser importada e
aparecer na janela anterior, mas ela ainda no foi inserida no projeto. Antes de a
inserirmos, vamos criar a biblioteca do JasperReports. Para isso, clique no boto
Create. Em Library Name entre com o valor JasperReports-3.7.5 (sem as
aspas) e clique em OK. Note que eu vou manter a verso do JasperReports utilizado
nas partes anteriores do tutorial, sendo assim sua verso pode variar dependendo de
quando voc estiver seguindo esse tutorial, visto que novas verses do JasperReports

so lanadas frequentemente. Se a verso que voc estiver usando for mais nova, vamos
dizer, 3.7.6, defina um nome da biblioteca que reflita a verso utilizada, ou seja
JasperReports-3.7.6.
Feito isso, a janela Customize Library ser exibida. Clique no boto Add
JAR/Folder. Como j fizemos isso uma vez nas partes anteriores do tutorial, o projeto
original j tem essa biblioteca configurada com os JARs necessrios. Ento vamos uslos. Procure pela pasta do projeto original (TutorialRelatorios). Dentro dela, entre na
pasta lib. Dentro da pasta lib, existir uma pasta chamada JasperReports-3.7.5. O
nmero da verso pode variar de acordo com a sua verso. Entre nela, selecione todos
os JARs e clique no boto Add JAR/Folder. O NetBeans vai perguntar se voc quer
criar um diretrio com o nome da biblioteca dentro da pasta lib do projeto atual
(TutorialRelatoriosWeb). Diga que sim e os JARs sero listados na janela Customize
Library. Clique em OK.
Novamente a janela Add Library ser exibida, agora contendo a tambm a biblioteca
do JasperReports que acabamos de configurar. Selecione tanto a biblioteca do
JasperReports quanto a biblioteca do MySQL e clique no boto Add Library. Agora
as bibliotecas sero adicionadas no projeto.
Ainda na janela de propriedades, procure a categoria Sources (primeira) e selecione-a.
Vamos criar agora o diretrio onde guardaremos os nossos fontes do relatrio. Na tabela
Source Package Folders, clique no boto Add Folder. Sero exibidas os
diretrios contidos no projeto. Crie ento uma nova pasta, chamada relatorios (sem
acentos e sem aspas), selecione-a e clique em Open. A pasta ser referenciada na
tabela. Clique duas vezes na clula correspondente coluna Label da pasta, preencha
com Relatrios (sem as aspas) e tecle <ENTER> para trocar o Label da pasta. Esse
Label vai ser utilizado para mostrar a pasta de relatrios na rvore do projeto.
Estamos quase l. Por fim, ainda na janela de propriedades, selecione a categoria
Packaging, dentro da categoria Build. Em Exclude From WAR File, adicione
uma vrgula e o valor **./*.jrxml (sem as aspas). Isso far com que os nossos
arquivos fonte de relatrios no sejam empacotados no arquivo WAR. O valor final do
campo deve ficar assim: **/*.java,**/*.form, **/*.jrxml (sem as aspas). Pronto!
Clique em OK na janela de propriedades e aguarde o NetBeans escanear as novas
configuraes do projeto.
Agora, abra o projeto anterior, v na pasta de Relatrios dele, copie o arquivo
ClientesPorNome.jrxml e cole na pasta Relatrios do novo projeto. Ainda no feche
o projeto anterior. No projeto atual, abra o relatrio que foi copiado e faa um Preview
dele para ver se est tudo ok. Lembre-se que o datasource correto (Sakila JDBC) tem
que estar selecionado l na barra de ferramentas do NetBeans. Se o relatrio for
renderizado e os dados aparecerem porque est tudo ok.
At agora nenhuma novidade. Criamos e configuramos o novo projeto e copiamos e
testamos o arquivo de relatrio que j fizemos para o novo projeto. Agora vamos s
novidades.
Vamos criar um Servlet que vai ser responsvel em pegar os possveis dados do request
que sero usados como parmetros para os relatrios e invocar o JasperReports para

criar o relatrio. O funcionamento parecido com o que fizemos no nosso programa


desktop, entretanto agora no iremos mais criar um JFrame para exibir os relatrios,
pois estamos usando um navegador no mesmo? O que o nosso Servlet vai fazer
criar diretamente um arquivo .pdf do relatrio e mandar exibir no navegador caso haja
algum plugin para leitura de PDF instalado ou ento o navegador vai sugerir que voc
faa o download do arquivo gerado.
Em Source Packages, crie trs pacotes: tutorialrelatoriosweb.jdbc,
tutorialrelatoriosweb.servlets e tutorialrelatoriosweb.util (todos sem as aspas). V
no projeto anterior, no pacote tutorialrelatorios.jdbc, copie a classe
ConnectionFactory e cole no pacote tutorialrelatoriosweb.jdbc do novo projeto. Se
quiser, feche o projeto anterior. Agora no novo projeto, v na pasta
tutorialrelatoriosweb.util e crie uma classe com o nome de ReportUtils (sem as
aspas). Ainda no vamos implementar nada nela. Feito isso, clique com o boto direito
no pacote tutorialrelatoriosweb.servlets, v em New -> Servlet. Se a opo Servlet
no estiver sendo exibida, selecione Other e em Categories selecione Web e em
File Types escolha Servlet e clique em Next.
O assistente para criar um novo Servlet ser exibido. Em Class Name preencha com
ReportServlet (sem as aspas) e clique em Next. Tanto Servlet Name quanto
URL Pattern vo ser deixados da forma que o NetBeans sugeriu, ou seja,
ReportServlet e /ReportServlet respectivamente. Clique em Finish.
O NetBeans vai gerar por padro uma implementao padro do mtodo
processRequest(). Faa com que o seu fique assim:
1 protected

void
processRequest(HttpServletRequest
HttpServletResponse response)

2
throws ServletException, IOException {

3
4

OutputStream out = null;

5
6

// aqui ns geramos o relatrio...

7
8

if ( out != null ) {

9
10
11
12}

out.close();
}

request,

Note que ainda no implementamos o mtodo processRequest(). Da mesma forma


que fizemos no projeto anterior, vamos agora criar um mtodo utilitrio na classe
ReportUtils que vai ser responsvel em gerar o relatrio. Segue a implementao
comentada da classe ReportUtils.
tutorialrelatoriosweb.util.ReportUtils.java
1 package tutorialrelatoriosweb.util;
2
3 import java.io.IOException;
4
5

import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;

6
import java.util.Map;

7
8

import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRException;

9 import net.sf.jasperreports.engine.JRExporter;
10import net.sf.jasperreports.engine.JRExporterParameter;
11import net.sf.jasperreports.engine.JasperFillManager;
12import net.sf.jasperreports.engine.JasperPrint;
13import net.sf.jasperreports.engine.export.JRPdfExporter;
14
/**

15
16

* Classe com mtodos utilitrios para gerar relatrios.


*

17
* @author David Buzatto

18

*/

19

public class ReportUtils {

20
21

/**

22

* Gera o relatrio em PDF.

23

24

* @param inputStream InputStream que contm o relatrio.

25

* @param parametros Parmetros utilizados pelo relatrio.

26
27para

* @param conexao Conexo utilizada para a execuo da query.


* @param response HttpServletResponse que ser usado como base

28

* gerar o relatrio.

29

* @return O OutputStream do HttpServletResponse passado.

* @throws JRException Caso ocorra algum problema na gerao do


relatrio.

30
31

* @throws IOException Caso ocorra algum problema na obteno do

32

* OutputStream.

33

*/

34

public static OutputStream createPDFReport(

35

InputStream inputStream,

36

Map<String, Object> parametros,


Connection conexao,

37

HttpServletResponse

38IOException {

response

throws

JRException,

39
40

// configura o content type do response

41

response.setContentType( "application/pdf" );

42
43
44

// obtm o OutputStream para escrever o relatrio


OutputStream out = response.getOutputStream();

45
46

/*
*

Cria

um

JasperPrint,

que

verso

preenchida

47relatrio,
48

* usando uma conexo.

49

*/

50

JasperPrint jasperPrint = JasperFillManager.fillReport(

do

inputStream, parametros, conexao );

51
52

// Exporta em PDF, escrevendo os dados no output stream do


response.

53
54

JRExporter exporter = new JRPdfExporter();

55

exporter.setParameter( JRExporterParameter.JASPER_PRINT,

56

jasperPrint );
exporter.setParameter( JRExporterParameter.OUTPUT_STREAM,

57

out );

58
59

// gera o relatrio

60

exporter.exportReport();

61
62

// retorna o OutputStream

63
return out;

64
65

66
67

68
69
70

Como vocs podem perceber, o mtodo createPDFReport() da classe ReportUtils


gera um relatrio em PDF e o escreve no OutputStream do response do Servlet. Caso
vocs queiram outros tipos de exportao, basta mudar o tipo do exportador. Clicando
aqui, vocs podem ver a documentao da interface JRExporter e de todas as classes
que a implementam. Note que ao mudar o exportador, voc tambm precisa alterar o
content type do response para refletir o tipo de arquivo gerado.
Vamos agora atualizar o nosso Servlet. O mtodo processRequest() vai ficar assim:
1 protected
2

void
processRequest(HttpServletRequest
HttpServletResponse response)

request,

3 throws ServletException, IOException {


4
5

OutputStream out = null;

6
7

// obtm o relatrio compilado


InputStream

inputStream

8 "/ClientesPorNome.jasper" );

getClass().getResourceAsStream(

9
10

// preenche o mapa de parmetros

11

Map<String, Object> parametros = new HashMap<String, Object>();

12

parametros.put( "primeiroNome", "D%" );

13
14

try {

15
// gera o relatrio e atribui o OutputStream gerado

16

out = ReportUtils.createPDFReport( inputStream, parametros,

17
ConnectionFactory.getSakilaConnection(), response );

18
19

} catch ( SQLException exc ) {

20
21

exc.printStackTrace();
} catch ( JRException exc ) {

22
23

exc.printStackTrace();
} finally {

24
25

// se no aconteceu nenhum problema, fecha o output stream

26

if ( out != null ) {
out.close();

27
}

28
29
}

30
31}
32

Com isso feito, rode a aplicao e aponte o navegador para o endereo


http://localhost:8084/TutorialRelatoriosWeb/ReportServlet&#8221; (sem as aspas).
Por padro o Tomcat usado em desenvolvimento no NetBeans roda na porta 8084.
Certifque-se que o seu est rodando nesta porta e se no estiver, use a porta correta. Se
voc seguiu corretamente o tutorial at aqui, ser gerado ento um .pdf com todos os
clientes que tenham o primeiro nome iniciando com a letra D (veja o parmetro
primeiroNome passado para o relatrio).
Note que agora, para passar parmetros para o relatrio, basta voc obter os parmetros
pelo request e ento adicionar os parmetros desejados no mapa de parmetros do
relatrio. Se quiser outros tipos de exportao, por exemplo, para Excel, basta criar um
novo mtodo na classe ReportUtils, que configura o content type apropriado
(application/ms-excel) e o exportador necessrio (JRXlsExporter ou JRXlsxExporter).
Tanto a passagem de parmetros quanto a gerao de outros tipos de arquivos ficam
como exerccio para vocs. O Servlet ReportServlet pode ser generalizado tambm,
permitindo que o nome do arquivo do relatrio a ser gerao seja passado via request :).
Com isso terminamos nosso tutorial sobre relatrios em Java! Espero que tenham
gostado! Para baixar o projeto criado nesta parte, clique aqui. Nos prximos tutoriais
iremos aprender a usar a biblioteca JavaScript jQuery, que extremamente til e facilita
muito a nossa vida.
Ento isso pessoal! Grande abrao a todos! At a prxima ;)

Você também pode gostar