Relatórios em JSF
Prof. Fernando Freitas
Esp. em Gestão e Docência Universitária/UNIFIMES
[email protected]Introdução
Aplicações normalmente precisam de algum tipo
de relatório.
Em Java existem alguns frameworks que podem
ser utilizados para facilitar a geração destes
relatórios.
Dentre os frameworks para desenvolvimento de
relatórios em java, seja para web ou não, temos
o JasperReports, que pode utilizar como
interface gráfica o iReport ou o Jaspersoft Studio.
O que é JasperReports
JasperReports
Framework open source escrito em Java para geração de
relatórios.
Biblioteca motor que transforma o arquivo JRXML em um
relatório exportado para uma das extensões suportadas
(PDF, HTML, etc) usando a fonte de dados especificada
Design definido via XML
Após codificado, o arquivo deve ser compilado, gerando
assim um arquivo .jasper
Desenvolvimento trabalhoso.
O que é iReport
Ferramenta que visa facilitar a construção de relatórios
(layout) utilizando a biblioteca JasperReports através de
uma interface gráfica desenvolvida em Swing.
Fornece suporte à construção de relatórios complexos.
Permite inserir objetos como: textos estáticos, figuras
geométricas, imagens, gráficos, sub relatórios entre
outros.
Elimina a necessidade de manipulação direta dos
arquivos JRXML.
Baseado no Netbeans, foi a interface padrão do
JasperReports até versão 5.5.0.
O que é Jaspersoft Studio
Ferramenta de design oficial para construção de relatórios
JasperResports a partir da versão 5.5.0.
Baseada no eclipse, é uma ferramenta livre e open source que
permite a criação de layouts sofisticados que contenham
gráficos, imagens, sub-relatórios, tabelas cruzadas e muito
mais.
Permite o acesso a dados através de JDBC, TableModels,
JavaBeans, fontes de XML, Hibernate, CSV entre outros.
Oferece suporte para publicação de relatórios em PDF, RTF,
XML, XLS, CSV, HTML, XHTML, texto, DOCX ou OpenOffice.
Por ser a versão oficial do JasperReports atualmente,
utilizaremos o Jaspersoft Studio em nossas aulas.
Fluxo de Execução de um Relatório
Fonte: http://community.jaspersoft.com/wiki/introduction-jaspersoft-studio
Conceitos básicos
Antes de iniciarmos a criação de um relatório
utilizando o Jaspersoft Studio, é necessário
conhecermos a definição de alguns termos
que serão necessários, como por exemplo:
Campos
Parâmetros
Variáveis
Expressões
Seções ou bandas.
Campos
Campos (Fields) são “áreas específicas” no relatório que
receberão diretamente os dados das colunas referenciadas.
Ex:
<field name=“DataCompra” class=“java.sql.Date”/>
Quando precisamos exibir o valor de um campo, utilizamos a
expressão $F{nome_do_campo}. Ex:
Data da compra = $F{DataCompra}
Parâmetros
Parâmetros são dados passados para a operação de
preenchimento, que não podem ser encontrados
normalmente na fonte de dados.
<parameter name=“TituloDoRelatorio” class=“java.lang.String”/>
Passados via código Java, através de um objeto HashMap. Ex:
HashMap parametros = new HashMap( );
parametros.put( “Cliente”, “Fulano de Tal” );
Quando precisamos exibir o valor de um parâmetro,
utilizamos a expressão $P{nome_do_parametro}. Exemplo
de uso na consulta do relatório:
SELECT * FROM cliente WHERE cliente = $P{Cliente}
Variáveis
Variáveis são utilizadas para armazenar resultados
temporários necessários para geração do relatório
podem referenciar tipos internos de cálculos, como contagem (count),
soma (sum), média (average), menor (lowest), maior (highest), etc. Ex:
<variable name=“SomaValorTotalCompra” class=“java.lang.Double”
calculation=“Sum”>
<variable expression> $F{ValorProduto} </variable expression>
</variable>
Quando precisamos exibir o valor de uma variável,
utilizamos a expressão $V{nome_do_variavel}. Ex:
O valor total da compra é de $V{SomaValorTotalCompra} reais
Variáveis
A ordem em que as variáveis são declaradas no relatório é
importante.
Podemos definir o nível no qual uma variável irá ser
inicializada. Pode ser no início do relatório (uma única vez), a
cada página, coluna ou grupo.
<variable name=“SomaValorTotalCompra” class=“java.lang.Double”
resetType=“Page” calculation=“Sum”>
<variable expression> $F{ValorProduto} </variable expression>
<initialValueExpression> new Double( 0 )
</initialValueExpression>
</variable>
Variáveis internas da ferramenta: PAGE_NUMBER,
COLUMN_NUMBER, REPORT_COUNT, PAGE_COUNT,
COLUMN_COUNT.
Expressões
Expressões (Expressions) são utilizadas para especificar o
conteúdo de campos de texto, na realização de cálculos
freqüentes
Todas elas são expressões Java que podem conter em sua
sintaxe:
campos
parâmetros
variáveis de relatório
Exemplo de uma expressão:
<textFieldExpression> “Sr.(a) ” + $P{Cliente} + " realizou um total de
compras no valor de " + $V{SomaValorTotalCompra} + " no dia " +
(new SimpleDateFormat("dd/MM/yyyy"))
.format($F{DataCompra}) + "."
</textFieldExpression>
Layout
O JasperReports divide o layout do relatório em áreas
“pré-definidas”, chamadas seções ou bandas.
As seções ou bandas, levam em consideração a estrutura
visual de um relatório. São elas: background, title,
pageHeader, columnHeader, detail, columnFoter,
pageFooter, lastPageFooter, summary e noData.
Seções do layout do relatório
O conteúdo colocado na banda background é exibido como plano de fundo
das páginas do relatório. Por padrão este é exibido em todas as páginas, mas
isto pode ser configurado.
O conteúdo da banda title aparece somente uma vez no começo do
relatório.
O que definimos na banda pageHeader aparece no alto de cada página do
mesmo.
Esta parte pode, por exemplo, conter a data/hora e/ou o nome da organização.
O columnHeader apresenta o título de cada coluna existente no relatório. É
usado por exemplo, para apresentar os nomes dos campos que você está
exibindo no relatório.
Por exemplo do “Nome do empregado”, “Hora de Início”, “Hora de término”,
“Horas trabalhadas”, etc.
Seções do layout do relatório
O detail é a banda onde os valores dos campos vindos de sua fonte de dados serão
apresentados. Por exemplo, “Jorge Horacio”, “12:00h”, “18:00h”, “06 horas”
O columnFooter pode indicar a soma de alguns dos campos. Por exemplo “Total de
horas trabalhadas: 180”
O pageFooter aparece no final de cada página. Pode conter por exemplo, o número da
página como “1 de 7”.
O lastPageFooter permite colocar uma informação diferenciada no rodapé da última
página.
O summary é a banda onde a informação inferida a partir dos dados da banda “detalhe”
é indicada.
Por exemplo, após ter listado as horas trabalhadas para cada empregado na banda “detail”, o
total de horas trabalhadas para cada empregado pode ser apresentado em um gráfico de
pizza.
A banda noData é impressa quando não existem dados para impressão no
relatório.
Seções de agrupamento
Às vezes pode ser necessário agrupar algumas informações em comum no seu
relatório.
O JasperSoft Studio permite que você crie seções adicionais para cada grupo
desejado, sendo elas a Group Header e a Group Footer.
A banda Group Header é a banda de cabeçalho do grupo e normalmente exibe as
informações sobre o grupo (ex: nome do grupo), antes que as informações agrupadas
sejam exibidas.
A banda Group Footer é a banda de rodapé do grupo e normalmente exibe
informações finais do grupo (ex: total de registro no grupo), após as informações
agrupadas terem sido exibidas.
Exemplo:
Mamíferos Group Header
Cavalo, Vaca, Elefante. Dados agrupados
Total de Mamíferos: 3 Group Footer
Principais Seções do Layout de um Relatório
Criação do Relatório
O relatório pode ser desenvolvido diretamente no software
do Jaspersoft Studio, que pode ser obtido no endereço
http://community.jaspersoft.com/download, ou pode-se
incluir um plugin no eclipse que permite a criação e edição do
relatório dentro do próprio eclipse. Utilizaremos a segunda
opção.
Adicionando o plugin Jaspersoft
Clique no menu Help >
Eclipse Marketplace
Adicionando o plugin Jaspersoft
Pesquise por jaspersoft
studio
Em seguida clique no
botão Install.
Siga os passos da
instalação.
Ao concluir a instalação,
reinicie o Eclipse.
Criando um Relatório Simples
Antes de começar, crie o pacote
relatorios
Acesse o menu File > New > Jasper
Report
Nesse ponto, você pode optar por
criar um relatório em branco (mais
trabalhoso, porém mais flexível) ou
utilizar um dos modelos oferecidos.
Para o nosso exemplo, selecione o
modelo Coffee
Clique em Next
Criando um Relatório Simples
Indique o local onde o
relatório deverá ser salvo.
Em nosso exemplo, vamos
deixar dentro do pacote
relatorios.
Clique em Next.
Criando um Relatório Simples
Neste ponto, você deve
selecionar uma fonte de dados.
O Jaspersoft Studio provê
suporte a diversas fontes de
dados: JDBC, Hibernate, etc.
Se não existir nenhuma
configurada, clique em New.
Se existir, selecione-a e pule os
3 próximos slides desta
apresentação.
Criando uma Nova Fonte de Dados
Nesta tela, selecione o
tipo da fonte de dados.
Em nosso exemplo
iremos trabalhar com
conexão JDBC, então
selecione a opção
Database JDBC
Connection.
Clique em Next
Criando uma Nova Fonte de Dados
Nesta tela, informe os
dados da conexão
Qual o driver?
Qual a url do banco de dados?
Qual o usuário?
Qual a senha?
Após informar os dados
acima, alterne para a aba
Driver Classpath.
Criando uma Nova Fonte de Dados
Nesta aba, informe o conector
(arquivo .jar) do banco. Em nosso
exemplo, informe o conector
MySQL utilizado nos exemplos
anteriores. Se você não possui, ele
pode ser obtido no endereço:
http://dev.mysql.com/downloads/c
onnector/j/
Clique no botão Test. Se os dados
foram informados corretamente,
você deverá obter uma mensagem
de sucesso. Caso contrário, revise
os dados informados.
Clique em Finish.
Construindo a Consulta
Com a fonte de dados
selecionada, informe o
código SQL para obter
os dados que irão
preencher o relatório.
Em nosso exemplo,
digite: select * from
usuario
Clique em Next.
Selecionando os Campos
Se a consulta estiver correta,
esta tela deve exibir os
campos retornados por ela,
para que você selecione
apenas os que serão
exibidos no relatório.
Em nosso exemplo,
selecione os campos: id,
nome, email e fone.
Clique em Next.
Selecionando o(s) campo(s) de
agrupamento(s)
Nesta tela, você deve
informar o(s) campo(s)
pelo qual os registros
serão agrupados.
Em nosso exemplo, não
haverá agrupamento de
informações, logo, não
selecione nenhum.
Clique em Finish.
Desenhar o Relatório
Após concluir, o
eclipse deve
alternar para a
perspectiva
Report Design
que permite a
edição do
relatório.
Dicas
É possível adicionar máscaras de formatação aos valores do
tipo Date e Numérico. Para isto, selecione o campo a ser
formatado, vá até as propriedades e selecione a aba Text
Field. Localize a opção Pattern, clique na reticências e
selecione o padrão desejado ou crie o seu próprio.
Se algum campo estiver com valor nulo, por padrão será
impresso a string null. Para alterar isto, vá até as
propriedades e selecione a aba Text Field. Procure pela
opção Blank when null e marque-a.
Compilar o relatório
Após o desenho do relatório, devemos compilá-lo.
Esse processo corresponde a gerar uma representação em formato
binário do relatório.
Resultado da compilação é um arquivo com a extensão .jasper.
É essa representação que usamos com o JasperReport para
“preencher” o relatório.
Para que o eclipse faça a compilação e exibição dos arquivos
.jasper, clique com o botão direito no nome do projeto e acesse a
opção JasperReports > Toggle JasperReports Nature.
A partir daí, a compilação do arquivo JRXML no eclipse é feita
juntamente com a do projeto. Se a opção Build Automatically
estiver ativa, ela deve ocorrer sempre que uma modificação for
salva.
Chamar o Relatório no Java
Uma vez compilado o relatório, pode-se chamar o relatório
via Java, para que a aplicação exiba os relatórios desejados.
A seguir conheceremos algumas classes que ajudam nesta
tarefa.
Atenção: É possível compilar o arquivo JRXML e gerar o arquivo .jasper via
código java. Contudo, a menos que isto seja fundamental, recomenda-se
compilá-lo previamente e só efetuar as requisições ao .jasper via código
java, de forma a evitar constantes compilações a cada nova requisição do
relatório.
Carregar o relatório
Classe JRLoader
Principais Métodos:
loadObjectFromFile(java.lang.String str);
loadObject(java.io.File file)
loadObject(java.net.URL url)
loadObject(java.io.InputStream is);
Preencher o relatório
Classe JasperFillManager
Principal método: fillReport (estático)
Retorna objeto JasperPrint
Assinatura:
JasperPrint fillReport(
String sourceFileName,
HashMap parameters,
Connection connection);
Preencher o relatório (cont.)
Parâmetros de fillReport:
String sourceFileName: corresponde ao nome do
relatório compilado (.jasper).
HashMap parameters: lista de parâmetros do
relatório (e.g., título, data, sessão)
Connection connection: conexão (JDBC) com a
fonte de dados utilizada para preencher o
relatório.
Exportar o relatório
JRPdfExporter, HtmlExporter, JRXlsExporter, JROdsExporter, JRDocxExporter...
Classes úteis quando queremos exportar o relatório para os formatos pdf, html, xls, ods e
docx respectivamente.
Exemplos:
JRPdfExporter jrPdf = new JRPdfExporter();
jrPdf. exportReport(); //exporta para pdf
HtmlExporter jrHtml = new HtmlExporter();
jrHtml. exportReport(); //exporta para html
JRXlsExporter jrXls = new JRXlsExporter();
jrXls. exportReport(); //exporta para excel
JROdsExporter jrOds = new JROdsExporter();
jrOds. exportReport(); //exporta para ods
E assim sucessivamente de acordo com o formato desejado...
Execução de um Relatório
Chamar o Relatório via Java
Adicione os arquivos abaixo dentro de WebContent > WEB-INF > lib.
Eles serão necessários na geração e exportação dos relatórios.
commons-collections-x.x.x.jar
commons-digester-x.x.jar
commons-logging-x.jar
groovy-all-x.x.x.jar
iText-x.x.x.jar
jasperreports-x.x.x.jar
poi-x.x-x.jar
Se não houver, crie o pacote util.
Crie uma classe chamada RelatorioUtil.java
Classe RelatorioUtil.java
public class RelatorioUtil {
public static StreamedContent geraRelatorio(HashMap<String, Object> parametrosRelatorio, JasperReport
relatorioJasper, Connection conn) throws Exception {
StreamedContent arquivoRetorno = null;
try {
FacesContext context = FacesContext.getCurrentInstance();
String caminhoRelatorio = context.getExternalContext().getRealPath("/");
JasperPrint impressoraJasper = JasperFillManager.fillReport(relatorioJasper, parametrosRelatorio, conn);
String caminhoArquivoRelatorio = caminhoRelatorio + File.separator + "relatorio.pdf";
File arquivoGerado = new java.io.File(caminhoArquivoRelatorio);
JRPdfExporter tipoArquivoExportado = new JRPdfExporter();
tipoArquivoExportado.setExporterInput(new SimpleExporterInput(impressoraJasper));
tipoArquivoExportado.setExporterOutput(new SimpleOutputStreamExporterOutput(arquivoGerado));
tipoArquivoExportado.exportReport();
arquivoGerado.deleteOnExit();
InputStream conteudoRelatorio = new FileInputStream(arquivoGerado);
arquivoRetorno = new DefaultStreamedContent(conteudoRelatorio, "application/pdf", "relatorio.pdf");
} catch (JRException e) {
throw new Exception("Não foi possível gerar o relatório.", e);
} catch (FileNotFoundException e) {
throw new Exception("Arquivo do relatório não encontrado.", e);
}
return arquivoRetorno;
}
}
Chamar RelatorioUtil.java
Altere sua classe UsuarioBean.java e adicione o código a seguir. Faça os import necessários:
private StreamedContent retorno;
private Integer tipo;
public StreamedContent getRetorno() { imprimir(); return retorno; }
public void setRetorno(StreamedContent retorno) { this.retorno = retorno; }
public Integer getTipo() { return tipo; }
public void setTipo(Integer tipo) { this.tipo = tipo; }
public void imprimir() {
String relatorioJasper = new String();
relatorioJasper = "/relatorios/usuarios.jasper";
FacesContext facesContext = FacesContext.getCurrentInstance();
Connection conn = null;
try {
URL urlRelatorio = getClass().getResource(relatorioJasper);
JasperReport jr = (JasperReport) JRLoader.loadObject(urlRelatorio);
conn = ConexaoFactory.abreConexao();
this.retorno = RelatorioUtil.geraRelatorio(null, jr, conn);
} catch (Exception ex) {
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao visualizar relatorio", "Detalhes: "+
ex.getMessage()));
} finally {
try {
if(conn != null)
ConexaoFactory.fechaConexao(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Chamando no xhtml
Altere sua página de listagem de usuarios e
acrescente o código abaixo imediatamente antes da
tag </h:form>:
<p:commandButton ajax="false" value="Emitir Relatório">
<p:fileDownload value="#{usuarioBean.retorno}"/>
</p:commandButton>
Enviando parâmetros
para o Relatório
Relatório com parâmetros
Altere a página de listar usuarios e adicione o código abaixo
para criar uma nova coluna no datatable.
<p:column width="20%" headerText="Relatório">
<p:commandLink value="Gerar PDF" ajax="false">
<f:setPropertyActionListener
target="#{usuarioBean.selecionado}" value="#{us}"/>
<p:fileDownload value="#{usuarioBean.usuarioRetornado}“/>
</p:commandLink>
</p:column>
Relatório com parâmetros
Altere UsuarioBean.java e adicione o código abaixo:
private StreamedContent usuarioRetornado;
public StreamedContent getUsuarioRetornado() {
imprimirUsuario();
return usuarioRetornado;
}
public void setUsuarioRetornado(StreamedContent usuarioRetornado) {
this.usuarioRetornado = usuarioRetornado;
}
private void imprimirUsuario() {
String relatorioJasper = new String();
relatorioJasper = "/relatorios/usuario.jasper";
FacesContext facesContext = FacesContext.getCurrentInstance();
Connection conn = null;
try {
URL urlRelatorio = getClass().getResource(relatorioJasper);
JasperReport jr = (JasperReport) JRLoader.loadObject(urlRelatorio);
HashMap<String, Object> parametro = new HashMap<String, Object>();
parametro.put("id", selecionado.getId());
conn = ConexaoFactory.abreConexao();
usuarioRetornado = RelatorioUtil.geraRelatorio(parametro, jr, conn);
} catch (Exception ex) {
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao visualizar relatorio", "Detalhes: "+ ex.getMessage()));
} finally {
try {
if(conn != null)
ConexaoFactory.fechaConexao(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Relatório com parâmetros
Crie um novo relatório
assim como o anterior.
Após criar o produto,
crie um novo
parâmetro (Botão
direito em Parameters >
Create Parameter)
chamado id
Relatório com parâmetros
Altere o tipo do
parâmetro criado
(Selecione o parâmetro
e vá em propriedades)
para java.lang.Integer.
Edite o XML e
acrescente no final da
sua consulta sql a
condição: where id =
$P{id}
Referências
SANTOS, Ismael H. F. Módulo III – Relatórios e Gráficos em Java. Disponível em:
http://www.tecgraf.puc-rio.br/~ismael/Cursos/Cidade_FPSW/aulas/Modulo3_Graficos_Relatorios/Java_R
elatorios.pdf
. Acesso em: 03 de junho de 2013.
TOFFOLI, Giulio. iReport – User Manual. Disponível em:
http://pt.scribd.com/doc/97594609/iReport-User-Manual. Acesso em: 05 de junho de 2013.
ARAÚJO, Everton Coimbra de. Desenvolvimento para WEB com Java. Florianópolis: Visual Books, 2010.
LUCKOW, Décio Heinzelmann; MELO, Alexandre Altair de. Programação Java para a WEB. São Paulo:
Novatec Editora, 2010.