Pra quem usa o SEAM e não gosta de fazer relatórios na mão com tags facelets segue uma contribuição:
package view;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.core.FacesMessages;
import org.jboss.seam.pdf.DocumentData;
import org.jboss.seam.pdf.DocumentStore;
import org.jboss.seam.pdf.DocumentData.DocType;
/**
* Esta é uma classe utilitária para exibir relatórios como PDF no Jboss SEAM.
*
* @author rodrigoy
*/
public abstract class ReportAction {
@In
FacesMessages facesMessages;
@In
EntityManager manager;
@In(value = "org.jboss.seam.pdf.documentStore", create = true)
DocumentStore documentStore;
/**
* Retorna o caminho para o relatório (arquivo ".jasper"). Esses arquivos
* ficam armazenados em /view/report. Assim sendo, esse método deve retornar
* algo como:
*
* "/report/listaDocumento.jasper"
*
* @return String contendo o caminho para o relatório.
*/
protected abstract String getReportPath();
/**
* Refere-se aos parâmetros específicos do relatorio, geralmente constituído
* de informações que vieram da tela ou do contexto. Uma implementação exemplo
* seria:
*
* Map<String, Object> params = new HashMap<String, Object>();
* params.put("projetoId", projeto.getId());
* return params;
*
* @return Map<String, Object> com os parâmetros.
*/
protected abstract Map<String, Object> getParams();
@SuppressWarnings("deprecation")
public String print() {
String reportUrl = getReportPath();
try {
Map<String, Object> params = new HashMap<String, Object>();
// o entity manager deve ser informado para o Jasper
params.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, manager);
// obter os parâmetros específicos do relatório
params.putAll(getParams());
// obter o caminho real (file system) para o relatório
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
String reportUrlReal = request.getRealPath(reportUrl);
// imprimir o relatório para um stream em PDF
JasperPrint jasperPrint = JasperFillManager.fillReport(reportUrlReal, params);
ByteArrayOutputStream output = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, output);
// armazenar o relatório do DocumentStore do SEAM
String reportId = documentStore.newId();
DocumentData data = new DocumentData("Report #" + reportId , DocType.PDF, output.toByteArray());
documentStore.saveData(reportId, data);
// retornar para o caminho padrão do SEAM para exibição de relatórios
return "/seam-doc?docId=" + reportId;
} catch (Exception e) {
facesMessages.addFromResourceBundle("ERRO_RELATORIO",
new Object[] {reportUrl, e.getMessage()});
return null;
}
}
}
Uso:
package view;
import java.util.HashMap;
import java.util.Map;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import view.ReportAction;
import domain.Projeto;
@Name ("listaDocumentoReport")
public class ListaDocumentoReport extends ReportAction {
@In
Projeto projeto;
@Override
protected String getReportPath() {
return "/report/listaDocumento.jasper";
}
@Override
protected Map<String, Object> getParams() {
Map<String, Object> params = new HashMap<String, Object>();
params.put("projetoId", projeto.getId());
return params;
}
}
Na página xhtml:
<h:commandLink id="imprimir" value="#{messages.Imprimir}" action="#{listaDocumentoReport.print}"/>
Motivo: Fazer relatórios na mão é um saco. Use o iReport.
Débitos Técnicos:
- 1 decapreted em getRealPath
- Chumbamento em new DocumentData(“Report #” + reportId
Débitos Funcionais:
- Fazer injetar diretamente do contexto Seam para o Jasper
- Gerar outras coisas além de PDF