Olá pessoal, boa tarde.
Estou novamente por aqui, dessa vez para publicar como exportar o relatório gerado no iReport para PDF.
Primeiramente deveremos ter as seguintes libs em nossa app (WEB-INF/lib):
iText-2.1.0.jar jasperreports-3.7.4.jar jasperreports-applet-3.7.4.jar jasperreports-fonts-3.7.4.jar jasperreports-javaflow-3.7.4.jar poi-3.0.1-FINAL.jar commons-beanutils-1.8.3.jar commons-collections-2.1.1.jar commons-javaflow-20060411.jar commons-logging-1.1.1.jar commons-logging-api-1.1.1.jar
Algumas libs não são obrigatórias, mas coloquei-as para evitar erros posteriores.
Abaixo o XHTML reponsável por invocar o Managed Bean e preencher a query desejada. No meu caso trata-se de um relatório de pedidos do cliente, onde usuário poderá informar o nome do cliente, data início e data fim, ou pode simplesmente não preencher o filtro.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/resources/template.xhtml">
<ui:define name="login">
<ui:include src="/resources/usuarioAutenticado.xhtml" />
</ui:define>
<ui:define name="javascript">
<script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/jquery.maskedinput-1.2.2.js"></script>
<script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/jquery.validate.js"></script>
<script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/funcoes.js"></script>
</ui:define>
<ui:define name="centro">
<p:messages />
<p:outputPanel id="oplDialog" layout="block">
<p:dialog id="dlgMsg" header="#{msg['modalPanel.msgAlerta']}"
position="center" minWidth="300" width="300" visible="true"
resizable="false" modal="true" rendered="#{relatorioPedidosClienteController.exibeDialog}">
<h:panelGrid columns="1" cellspacing="5px">
<h:outputLabel id="oplMensagem" value="#{relatorioPedidosClienteController.mensagem}" styleClass="fonteAlerta" />
<p:commandButton id="cbtOk" value="#{msg['botao.ok']}" action="/index?faces-redirect=true" immediate="true" />
</h:panelGrid>
</p:dialog>
</p:outputPanel>
<p:panel id="pnlCorpoRelatorioCliente" style="position: relative; margin: auto; margin-top: 20px; width: 900px;">
<f:facet name="header">
<h:outputText value="Detalhes do Relatório de Pedidos do Cliente" />
</f:facet>
<h:panelGrid columns="3" columnClasses="col1, col2, col3">
<h:outputLabel styleClass="fontePadrao" value="#{msg['pedido.cliente.nome']}" />
<h:inputText id="iptNomeClientePesq" size="70" maxlength="100"
onkeyup="this.value = somenteCaracteres(this.value)"
value="#{relatorioPedidosClienteController.cliente.nmCliente}" />
<p:commandButton value="Pesquisar" action="#{relatorioPedidosClienteController.carregaClientesPeloNome}"
update="tabClientes" />
</h:panelGrid>
<p:outputPanel layout="block">
<p:dataTable id="tabClientes" value="#{relatorioPedidosClienteController.listaClientes}" var="cliente" rows="3"
width="700px" emptyMessage="#{msg['tabela.nenhumRegistroEncontrado']}" paginator="true"
paginatorPosition="bottom" style="position: relative; margin: auto; text-decoration: none; font-size: 12px;"
firstPageLinkLabel="#{msg['tabela.primeiroRegistro']}" nextPageLinkLabel="#{msg['tabela.proximoRegistro']}"
previousPageLinkLabel="#{msg['tabela.anteriorRegistro']}" lastPageLinkLabel="#{msg['tabela.ultimoRegistro']}"
selectionMode="single">
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['cliente.tabela.cpf']}" />
</f:facet>
<h:outputText value="#{cliente.nuCpf}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['cliente.tabela.cnpj']}" />
</f:facet>
<h:outputText value="#{cliente.nuCnpj}" />
</p:column>
<p:column sortBy="#{cliente.nmCliente}">
<f:facet name="header">
<h:outputText value="#{msg['cliente.tabela.nome']}" />
</f:facet>
<h:outputText value="#{cliente.nmCliente}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['cliente.tabela.cep']}" />
</f:facet>
<h:outputText value="#{cliente.nuCep}" />
</p:column>
<p:column>
<p:commandLink id="cdlSelecionaCliente" update="iptNomeClientePesq">
<h:graphicImage url="/img/tick.png" title="#{msg['botao.consultar']}" />
<f:setPropertyActionListener value="#{cliente}" target="#{relatorioPedidosClienteController.cliente}" />
</p:commandLink>
</p:column>
</p:dataTable>
</p:outputPanel>
<h:panelGrid columns="2" columnClasses="col1, col2">
<h:outputLabel styleClass="fontePadrao" value="Data Inicial:" />
<p:inputMask id="iptDataEmissao" mask="99/99/9999" maxlength="10" size="11" value="#{relatorioPedidosClienteController.dataInicio}">
<f:convertDateTime pattern="dd/MM/yyyy" timeZone="#{relatorioPedidosClienteController.timeZone}" />
</p:inputMask>
<h:outputLabel styleClass="fontePadrao" value="Data Final:" />
<p:inputMask id="iptDataVencimento" mask="99/99/9999" maxlength="10" size="11" value="#{relatorioPedidosClienteController.dataFim}">
<f:convertDateTime pattern="dd/MM/yyyy" timeZone="#{relatorioPedidosClienteController.timeZone}" />
</p:inputMask>
</h:panelGrid>
<f:facet name="footer">
<p:commandButton value="#{msg['botao.fechar']}" action="/index?faces-redirect=true"
immediate="true" />
<h:outputText value=" " />
<p:commandButton id="cbtGerarRelatorio" value="Gerar Relatório" action="#{relatorioPedidosClienteController.geraRelatorio}"
ajax="false" >
<p:ajax event="complete" update="oplDialog" />
</p:commandButton>
</f:facet>
</p:panel>
</ui:define>
</ui:composition>
</html>
Agora o ManagedBean responsável por passar os parâmetros para o relatório (arquivo .jasper) gerado durante a compilação do mesmo, e exportá-lo para pdf.
package br.com.notaroberto.controller;
import br.com.notaroberto.model.Cliente;
import br.com.notaroberto.util.Funcoes;
import br.com.notaroberto.util.HibernateUtil;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
@ManagedBean(name = "relatorioPedidosClienteController")
@ViewScoped
public class RelatorioPedidosClienteController {
private TimeZone timeZone = TimeZone.getDefault();
private JasperPrint impressao;
private HashMap<String, Serializable> parametroMap;
private FacesContext context;
private ServletContext servletContext;
private String mensagem, caminhoRelatorio;
private Date dataInicio, dataFim;
private boolean exibeDialog, exibeTabelaCliente;
private Cliente cliente;
private List<Cliente> listaClientes;
@PostConstruct
public void init() {
// Chamando ao instanciar o escopo de visao
cliente = new Cliente();
}
@PreDestroy
public void destroy() {
// A chamada eh realizada quando a pagina eh alterada
}
public String getMensagem() {
return mensagem;
}
public void setMensagem(String mensagem) {
this.mensagem = mensagem;
}
public boolean isExibeDialog() {
return exibeDialog;
}
public void setExibeDialog(boolean exibeDialog) {
this.exibeDialog = exibeDialog;
}
public boolean isExibeTabelaCliente() {
return exibeTabelaCliente;
}
public void setExibeTabelaCliente(boolean exibeTabelaCliente) {
this.exibeTabelaCliente = exibeTabelaCliente;
}
public Date getDataInicio() {
return dataInicio;
}
public void setDataInicio(Date dataInicio) {
this.dataInicio = dataInicio;
}
public Date getDataFim() {
return dataFim;
}
public void setDataFim(Date dataFim) {
this.dataFim = dataFim;
}
public TimeZone getTimeZone() {
return timeZone;
}
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
public List<Cliente> getListaClientes() {
return listaClientes;
}
public void setListaClientes(List<Cliente> listaClientes) {
this.listaClientes = listaClientes;
}
public void carregaClientesPeloNome() {
ClienteController clienteController = new ClienteController();
clienteController.carregaClientesPeloNome(cliente.getNmCliente());
setListaClientes(clienteController.getListaClientes());
}
public String montaSQL(Integer idCliente, String dataInicio, String dataFim) {
String sql = " 1 = 1";
if (!dataInicio.isEmpty() && !dataFim.isEmpty()) {
sql += " AND ( ped.DATA_EMISSAO BETWEEN STR_TO_DATE('" + dataInicio + "', '%d/%m/%Y') AND STR_TO_DATE('" + dataFim + "', '%d/%m/%Y') )";
}
if (idCliente != null) {
sql += " AND cli.ID_CLIENTE = '" + idCliente + "'";
}
sql += " GROUP BY cli.ID_CLIENTE, ped.ID_PEDIDO, prod.ID_PRODUTO, pp.ID_PED_PROD";
return sql;
}
public void geraRelatorio() {
context = FacesContext.getCurrentInstance();
servletContext = (ServletContext) context.getExternalContext().getContext();
caminhoRelatorio = servletContext.getRealPath("/relatorios/jasper/RelatorioPedidosCliente.jasper");
mensagem += "Caminho do relatório: " + caminhoRelatorio + "\n ";
mensagem += "Sistema Operacional: " + Funcoes.retornaSistemaOperacional().toLowerCase() + "\n ";
parametroMap = new HashMap<String, Serializable>();
String sql = montaSQL(cliente.getIdCliente(),
dataInicio != null ? Funcoes.formataDataEmString(dataInicio) : "",
dataFim != null ? Funcoes.formataDataEmString(dataFim) : "");
parametroMap.put("sql", sql);
/* criando novo cliente apos passagem de parametro para nova pesquisa */
cliente = new Cliente();
String dataIni = dataInicio != null ? Funcoes.formataDataEmString(dataInicio) : "00/00/0000";
String dataF = dataFim != null ? Funcoes.formataDataEmString(dataFim) : "00/00/0000";
String periodo = "Período de: " + dataIni + " a " + dataF;
parametroMap.put("periodo", periodo);
setExibeDialog(true);
enviarPdf();
}
public void enviarPdf() {
// Carrega o xml de definição do relatório
try {
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
// Configura o response para suportar o relatório
response.setContentType("application/pdf");
// response.addHeader("Content-disposition", "inline; filename=\"arquivo.pdf\"");
response.addHeader("Content-disposition", "attachment; filename=\"arquivo.pdf\"");
// Preenche o relatório com os parametros e o data source
impressao = JasperFillManager.fillReport(caminhoRelatorio, parametroMap, HibernateUtil.recuperaConexao());
// Exporta o relatório
JasperExportManager.exportReportToPdfStream(impressao, response.getOutputStream());
// Salva o estado da aplicação no contexto do JSF
context.getApplication().getStateManager().saveView(context);
// Fecha o stream do response
context.responseComplete();
} catch (Exception e) {
setExibeDialog(true);
mensagem += e;
}
}
}
Espero ter ajudado. Tive vários problemas para geração de relatórios em PDF, e pesquisando aqui e ali fui reunindo as informações e consegui montar algo que realmente funcionasse.
Abs,
Lessandro