Actionscript/ Actionscript Frameworks/ AMFPHP/ Flex/ Open-source

Gerar PDF de sua aplicação Flex para desenvolvedores PHP

Gerar PDF de sua aplicação Flex é super simples, existem hoje no mercado algumas soluções open-source para se gerar PDF à partir de sua aplicação Flex, a biblioteca que vou usar neste exemplo é a APDF uma biblioteca gratuita e que serve apenas para desenvolvedores que usam o php como linguagem de server-side.
Claro que você pode por outra vez usar outra linguagem de server-side para gerar o documento em PDF para asp por exemplo ou até para Java, mais ai já é por sua conta e risco.

Limitações do aPDF:

  • Não suporta PNG
  • Não suporta rawData
  • Não suporta embed de fontes
  • Não suporta manipulação final do encoder do Acrobat Reader

Ingredientes usados:

aPDF
Baixe a versão que usa o as3corelib, para fazer o encoder de imagem.

Primeiro passo que vou fazer é adicionar conteúdo ao meu aplicativo, para isso copie o código abaixo e coloque em seu aplicativo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application backgroundColor="#f4f4f4" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :XML id="lista" xmlns="">
	<root>
			<pedidos>
					<pedido>
					     <produto>
					     	<nome>Escova dentária</nome>
					     	<valor>400</valor>
					     </produto>
					     <produto>
					     	<nome>Creme Dental</nome>
					     	<valor>100</valor>
					     </produto>
					     <produto>
					     	<nome>Fio Dental</nome>
					     	<valor>50</valor>
					     </produto>
					     <produto>
					    	<nome>Sabonete</nome>
					    	<valor>10</valor>
					     </produto>
					</pedido>
			</pedidos>
	</root>
</mx>
 
	<mx :VDividedBox height="100%" width="100%">
	</mx><mx :VBox width="100%" height="50%">
		</mx><mx :ColumnChart dataProvider="{lista.pedidos.pedido.produto}" id="graficocoluna" width="100%" height="100%">
 
		</mx><mx :horizontalAxis>
					<mx :CategoryAxis dataProvider="{lista.pedidos.pedido.produto}" categoryField="nome"/>
			</mx><mx :series>
			</mx><mx :ColumnSeries displayName="Pedidos" yField="valor">
				</mx><mx :fill>
						<mx :SolidColor color="0x7BCE2A"/>
		<mx :Legend dataProvider="{graficocoluna}"/>
		</mx><mx :VBox width="100%" height="50%">
		</mx><mx :DataGrid dataProvider="{graficocoluna.dataProvider}" width="100%" height="100%">
			</mx><mx :columns>
				<mx :DataGridColumn headerText="Produto" dataField="nome"/>
				<mx :DataGridColumn headerText="Preço" dataField="valor"/>
			</mx>
 
		<mx :HBox width="100%" horizontalAlign="center" height="45" verticalAlign="middle">
			<mx :Button label="Gerar PDF"/>
		</mx>

Com o esqueleto pronto, é hora de programar o o aPDF para adicionar a imagem do gráfico e os resultados do datagrid para o documento pdf.

Primeiro passo é você baixar tanto a biblioteca aPDF e a as3corelib e coloca-las dentro da pasta src, lembre-se que ambas compartilham o mesmo diretório “com”, como diretório principal para o pacote de classes, então só jogar o as3corelib dentro do “com” e o apdf tbm, veja aqui como ficou o meu.

Caso você queira, só baixar aqui um arquevo zip que fiz para ambos, basta só arrastar o conteúdo desse zip para seu diretório src do projeto. Clique aqui para baixar o zip.

Outra coisa que fiz é colocar o diretório php que vem junto com o aPDF dentro do meu servidor XAMPP, na pasta htdocs.

Adicionando objetos ao meu arquevo PDF.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<mx :Script>
	< ![CDATA[
		import com.candymandesign.pdf.objects.APDFormat;
		import com.candymandesign.pdf.APDF;
 
				private var _pdfObject:APDF;
 
				public function gerarPDF():void{
 
						_pdfObject = new APDF();
						_pdfObject.addPage();
						_pdfObject.setPageSize(APDFormat.PAGE_SIZE_A4);
						_pdfObject.currentPage.addImage(graficocoluna,60,50,50);
						_pdfObject.export("http://localhost/apdf/apdf.php");
 
				}
	]]>
</mx>

Gerar a página em pdf é simples, veja que do código acima eu criei um objeto _pdfObject que deriva da instância da classe APDF, depois adiciono ai uma página com o método addPage().
Depois que executo o método addPage(), vou setar o formato desta minha página usando o método setPageSize(), no caso acima uso uma classe auxiliar que é a APDFFormat para gerar em A4; Logo eu pego a página atual ou seja currentPage e adiciono uma imagem usando o método addImage(), este método vem com parametros onde seto o primeiro que é o alvo ou seja uma imagem que venha da classe DisplayObject e depois seto a qualidade desta imagem que vai de zero até 100, o padrão dela é 60, e depois os valores de x, y para posicionar na página e larguar e altura da imagem.
No final de todo o processo de montar a página, etc, eu executo o método export, que aponta para meu arquevo apdf.php que recebe os valores e gera o pdf final.

O resultado do código final é o seguinte.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application backgroundColor="#f4f4f4" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
 
</mx><mx :Script>
	< ![CDATA[
		import com.candymandesign.pdf.objects.APDFormat;
		import com.candymandesign.pdf.APDF;
 
				private var _pdfObject:APDF;
 
				public function gerarPDF():void{
 
						_pdfObject = new APDF();
						_pdfObject.addPage();
						_pdfObject.setPageSize(APDFormat.PAGE_SIZE_A4);
						_pdfObject.currentPage.addImage(graficocoluna,60,50,50);
						_pdfObject.export("http://localhost/apdf/apdf.php");
 
				}
	]]>
</mx>
 
<mx :XML id="lista" xmlns="">
	<root>
			<pedidos>
					<pedido>
					     <produto>
					     	<nome>Escova dentária</nome>
					     	<valor>400</valor>
					     </produto>
					     <produto>
					     	<nome>Creme Dental</nome>
					     	<valor>100</valor>
					     </produto>
					     <produto>
					     	<nome>Fio Dental</nome>
					     	<valor>50</valor>
					     </produto>
					     <produto>
					    	<nome>Sabonete</nome>
					    	<valor>10</valor>
					     </produto>
					</pedido>
			</pedidos>
	</root>
</mx>
 
	<mx :VDividedBox height="100%" width="100%">
	</mx><mx :VBox width="100%" height="50%">
		</mx><mx :ColumnChart dataProvider="{lista.pedidos.pedido.produto}" id="graficocoluna" width="100%" height="100%">
 
			</mx><mx :horizontalAxis>
					<mx :CategoryAxis dataProvider="{lista.pedidos.pedido.produto}" categoryField="nome"/>
			</mx>
			<mx :series>
			</mx><mx :ColumnSeries displayName="Pedidos" yField="valor">
				</mx><mx :fill>
						<mx :SolidColor color="0x7BCE2A"/>
				</mx>
 
 
 
		<mx :Legend dataProvider="{graficocoluna}"/>
 
 
	<mx :VBox width="100%" height="50%">
		</mx><mx :DataGrid dataProvider="{graficocoluna.dataProvider}" width="100%" height="100%">
			</mx><mx :columns>
				<mx :DataGridColumn headerText="Produto" dataField="nome"/>
				<mx :DataGridColumn headerText="Preço" dataField="valor"/>
			</mx>
 
		<mx :HBox width="100%" horizontalAlign="center" height="45" verticalAlign="middle">
			<mx :Button label="Gerar PDF" click="gerarPDF()"/>
		</mx>

Ok, até ai tudo bem, geramos nosso primeiro PDF, só que é simples demais, vamos tentar adicionar uma série de opções ao meu pdf.

Outro exemplo é a adição de textos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
	</mx><mx :Script>
		< ![CDATA[
			import com.candymandesign.pdf.objects.APDFDocumentInfo;
			import com.candymandesign.pdf.objects.APDFormat;
			import com.igorcosta.ArquevoPDFUtil;
			import com.candymandesign.pdf.APDF;
 
 
			public function gerarPDF():void{
					var cms:APDF = new APDF();
					cms.addPage();
					cms.currentPage.addText(texto.text,10,10);
					cms.setOrientation(APDFormat.PORTRAIT);
					cms.export("http://localhost/apdf/apdf.php");
			}
 
		]]>
	</mx>
 
	<mx :Button x="500" y="370" label="Gerar PDF" click="gerarPDF()"/>
	<mx :RichTextEditor id="texto" x="239" y="31" title="Editor" width="570" height="331">
	</mx>

Criando um gerenciador de controle de impressão

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		import com.candymandesign.pdf.objects.APDFormat;
		import com.candymandesign.pdf.APDF;
 
			private var _arquevo:APDF;
 
			public function gerarPDF():void{
					_arquevo = new APDF();
					for (var i:int=1;i<=pgNumers.value;i++){
						_arquevo.addPage(String(i));
					}
					for (var j:int=0;j <_arquevo.getNumberOfPages();j++){
 
						_arquevo.getPageByID(j).addText("Algum texto criado",10,10,20);
					}
 					switch (formatoPage.selectedIndex){
							case 0:
									_arquevo.setPageSize(APDFormat.PAGE_SIZE_LETTER);
									break;
							case 1:
									_arquevo.setPageSize(APDFormat.PAGE_SIZE_A3);
									break;
							case 2:
									_arquevo.setPageSize(APDFormat.PAGE_SIZE_A4);
									break;
							case 3:
									_arquevo.setPageSize(APDFormat.PAGE_SIZE_A5);
									break;
 
							case 4: _arquevo.setPageSize(APDFormat.PAGE_SIZE_LEGAL);
									break;
 
							default:
									_arquevo.setPageSize(APDFormat.PAGE_SIZE_A4);
									break;
					}
						switch (orientacaoPage.selectedIndex){
								case 0:
									_arquevo.setOrientation(APDFormat.LANDSCAPE);
									break;
								case 1:
									_arquevo.setOrientation(APDFormat.PORTRAIT);
									break;
 
								default:
									_arquevo.setOrientation(APDFormat.PORTRAIT);
									break;
						}
		 				_arquevo.export("http://localhost/apdf/apdf.php");
			}
	]]>
</mx>
	<mx :Panel width="374" height="218" layout="absolute" title="Gerenciador APDF" x="10" top="27">
		</mx><mx :Form x="21" y="25">
			</mx><mx :FormItem label="Número de paginas">
				<mx :NumericStepper id="pgNumers" value="1" minimum="1" maximum="100" stepSize="1"/>
			</mx>
			<mx :FormItem label="Formato da pagina">
				</mx><mx :ComboBox id="formatoPage">
				</mx><mx :Array>
					</mx><mx :String> Carta </mx>
					<mx :String> A3 </mx>
					<mx :String> A4 </mx>
					<mx :String> A5 </mx>
					<mx :String> Legal </mx>
 
 
 
			<mx :FormItem label="Orientação">
				</mx><mx :ComboBox id="orientacaoPage">
				</mx><mx :Array>
					</mx><mx :String>Paisagem</mx>
					<mx :String>Vertical</mx>
 
 
 
 
		<mx :Button x="259" y="143" label="Gerar PDF" click="gerarPDF()"/>

Embora eu tenha usado o aPDF, ainda tem assunto para o próximo post, que neste caso usarei uma biblioteca mais robusta que o aPDF que é o alivePDF.

[Update] Alguns códigos exibidos neste post podem não aparecer corretamente, devido a um problema antigo em um plug-in para exibir código fonte. Pedimos desculpas.

2 thoughts on “Gerar PDF de sua aplicação Flex para desenvolvedores PHP

  1. Opa!

    Vi aqui seu post sobre gerar um pdf e fiquei com uma dúvida!
    Você citou que esta biblioteca free somente funciona com amf para php.
    Gostaria de saber o que é retornado pelo php como resultado.
    Um array, um objeto sei lá, pois creio eu, que a biblioteca independe de ser php. Se for retornado o tipo de dado esperado ela funcionaria com qualquer meio de comunicação.

    Eu estou com esta dúvida.
    Só para lembrar, estou começando com Flex, e utilizo um framework python como BackEnd.

    Obrigado

Comments are closed.