quarta-feira, 5 de maio de 2010

Unindo dois (ou mais) .jasper para obtenção de apenas um relatório

Enfrentei o problema de ter um relatório muito grande para ser gerado usando JasperReport. Nem com subrelatórios o maldito era gerado. Cheguei à conclusão que o iReport não funciona legal com relatórios cuja base é extensa (e depois encontrei alguns posts pela internet falando que a quebra de página do iReport/Jasper não funciona corretamente).

A solução que encontrei foi fazer dois arquivos .jasper diferentes que, juntos, compunham meu relatório. O problema na sequência foi unir esses dois .jasper para a obtenção de um único relatório. Segue minha solução fortemente baseada nesse post do GUJ:
public void imprimirRelatorio() {

ExternalContext econtext = getExternalContext();
InputStream stream;

List j = new ArrayList();

try {
Map params = new HashMap(); // preenche os parâmetros do relatório 1
stream =
econtext.getResourceAsStream("/WEB-INF/reports/rel1.jasper");
j.add(JasperFillManager.fillReport(stream, params));

params = new HashMap(); // preenche os parâmetros do relatório 2
stream =
econtext.getResourceAsStream("/WEB-INF/reports/rel2.jasper");
j.add(JasperFillManager.fillReport(stream, params));

JRPdfExporter exporter = new JRPdfExporter();
HttpServletResponse response =
(HttpServletResponse) econtext.getResponse();
FacesContext fcontext = FacesContext.getCurrentInstance();
ByteArrayOutputStream retorno = new ByteArrayOutputStream();

exporter.setParameter(JRExporterParameter.JASPER_PRINT_LIST, j);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, retorno);
exporter.setParameter
(JRPdfExporterParameter.IS_CREATING_BATCH_MODE_BOOKMARKS,
Boolean.TRUE);
exporter.exportReport();

byte[] retornoArray = retorno.toByteArray();

response.setContentType("application/pdf");
response.setContentLength(retornoArray.length);

OutputStream output = response.getOutputStream();
output.write(retornoArray);
output.flush();
output.close();

} catch (RuntimeException e) {
// logar e tratar exception
} catch (Exception e) {
e.printStackTrace();
} finally {

        try {
stream.close();
} catch (IOException e) {
// logar e tratar exception
}
}

fcontext.responseComplete();}

O código acima ainda está bem cru. Fica como excercício pra você melhorá-lo. :)

Nenhum comentário:

Postar um comentário