O Flex é uma ferramenta excepcional para o desenvolvimento de RIAs, mas deixa um pouco a desejar quando o assunto é impressão. Ele possui uma classe PrintJob para fazer impressão, mas não permite que você visualize o que vai ser impresso.

Por causa dessa deficiência o pessoal do www.kemelyon.com/bts (este site está fora do ar enquanto escrevo este artigo) desenvolveu o FlexReport, um componente que permite você montar modelos de relatórios, inserir dados nesses modelos, visualizar a impressão e enviar o documento para a impressora. O componente é distribuído sob a LGPL e pode ser baixado via SVN pela página do FlexReport no Google Code. Mas para facilitar eu já disponibilizo aqui o swc da biblioteca, traduzido para português.

Neste artigo pretendo mostrar como funcionam as principais classe dessa biblioteca. No próximo artigo, vou mostrar, na prática, como o FlexReport funciona.

A classe mais importante da biblioteca é a classe Report. Ela é responsável pela definição dos modelos do nosso relatório. Por “modelo de relatório” entenda-se um padrão que será aplicado a todos os relatórios de um determinado tipo. Um exemplo disso seria um relatório com o resumo geral das vendas do mês. Para fazer outro relatório, como o resumo das vendas por vendedor, por exemplo, você cria outro template, e por aí vai. É para isso que serve a classe Report.

Outro componente interessante é o PrintComponent. Como o próprio nome da classe diz, ele é um componente “imprimível”. O PrintComponent está para o relatório assim como o Canvas está para o Flex. Com ele você pode definir, por exemplo, o cabeçalho e o rodapé do seu relatório. Este componente tem propriedades como showInAllPages e showInFirstPage, o que o torna ainda mais específico para o uso como cabeçalho e rodapé. Mas nada impede que você crie um componente para o corpo do relatório usando o PrintComponent.

E por falar em corpo do relatório, tem também o componente Body. De novo como o nome diz, ele serve para delimitar o corpo do relatório, o espaço que se repetirá em todas as páginas. Geralmente a instância dessa classe terá largura e altura definidos como 100%, uma vez que ele deverá ocupar todo o espaço não ocupado pelos cabeçalho e rodapé.

Para a impressão de um DataGrid, você pode usar a classe ReportDataGrid. Ela estende a classe PrintDataGrid (que faz parte do Flex, não do FlexReport). Deve existir uma classe específica para impressão porque o DataGrid não foi feito para ser impresso, mas para ser mostrado na tela. Já o PrintDataGrid foi feito para controlar as quebras de páginas, para não mostrar metade de uma linha em uma página e a outra metade na página seguinte.

Esses quatro componentes (Report, PrintComponent, Body e ReportDataGrid) são os componentes visuais mais importantes. Vamos ver agora os componentes não-imprimíveis, que são fundamentais para gerar um relatório.

Para visualizar o relatório (antes de imprimir algo com o FlexReport você precisa visualizar o relatório primeiro) você usa uma instância da classe Preview. Pra resumir, ela é a tela que aparece na imagem abaixo. Para que um relatório seja mostrado nessa tela com seus thumbnails, é necessário apenas que você defina a propriedade doc dessa classe. Essa propriedade recebe uma instância da classe Document, que também faz parte do FlexReport.

preview_flexreport

A classe Document é o verdadeiro relatório, pronto para impressão. O FlexReport usa o modelo definido com a classe Report para gerar o relatório final, que será uma instância de Document. Simples assim. Para isso, a classe Document recebe até três parâmetros no seu construtor: o template, o dataprovider do template e o tamanho do papel.

O conceito de DataProvider dentro do FlexReport é interessante. Pense comigo: o DataProvider de um DataGrid tem que ser algo que seja “mostrável” em uma tabela, como um ArrayCollection ou um XML. Mas e o DataProvider de um relatório? Um relatório não é só tabela! Ele pode ter qualquer coisa. É por isso que podemos definir o DataProvider no FlexReport da forma como quisermos, porque a tabela pode ser apenas um dos itens do nosso relatório. Não existe uma classe específica para ser o DataProvider do nosso relatório, mas esse conceito é importante. O DataProvider do nosso relatório pode ser qualquer objeto, conforme vou mostrar no próximo artigo.

A classe PaperFormat serve para definirmos o tamanho do papel onde será impresso nosso relatório. Ela possui diversas constantes estáticas para isso, como PaperFormat.A4.

Bom, os principais conceitos foram cobertos nesse (extenso) artigo. Para não se tornar muito cansativo, vou deixar para mostrar como fazer um relatório no FlexReport no próximo artigo. Até lá!

#Edit @ 25/fev/09
Aqui está a segunda parte do artigo – em screencast!

#Edit @07/jun/2010
Aqui está um artigo sobre a lib do FlexReport para Flex 4!