Login   Register  
PHP Classes
elePHPant
Icontem

File: LEIAME

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Eustaquio Rangel de Oliveira Jr.  >  phpreports  >  LEIAME  >  Download  
File: LEIAME
Role: Documentation
Content type: text/plain
Description: Portuguese readme file
Class: phpreports
Report Generator
Author: By
Last change:
Date: 2003-03-13 14:48
Size: 37,383 bytes
 

Contents

Class file image Download
PHPReports LEIAME
escrito por TaQ (eustaquiorangel@yahoo.com)
Fevereiro 2003

	Tópicos
	
	1   - O que é o PHPReports ?
	2   - O que eu preciso para usar o PHPReports ?
	3   - Tem que pagar para usar ?
	4	 - Me conte como funciona
	4.1 - Estrutura do relatório
	5   - Um exemplo simples
	5.1 - Layout do relatório
	5.2 - Código PHP
	5.3 - Arquivo de layout XML
	6   - Arquivo DTD
	6.1 - Elemento REPORT
	6.2 - Elemento COL
	6.3 - Elemento ROW
	6.4 - Elemento HEADER
	6.5 - Elemento FOOTER
	6.6 - Elemento PAGE
	6.7 - Elemento FIELD
	6.8 - Elemento GROUP
	6.9 - Elemento GROUPS
	6.10- Elemento LINK
	6.11- Elemento XHTML
	7   - Validando seu documento 
	8   - Lista de arquivos
	9   - Considerações finais
	10  - Changelog
	11  - Indíce das funções PHP mais comuns nas classes do PHPReports
	12  - FAQ

	1 - O que é o PHPReports ?
	
		O PHPReports são algumas classes PHP, instruções XML e scripts
		XSLT para transformar o arquivo XML em código PHP. O código PHP
		gerado vai ser usado nas classes PHP pré-definidas.
		Eu comecei com a idéia quando eu precisei fazer todas as coisas que
		nós usavamos (na empresa que trabalho) em programas como Visual Basic
		e FoxPro, mas no browser, e uma das coisas que eu não encontrei foi
		como fazer e imprimir relatórios, usando uma consulta SQL, de um jeito
		fácil (não tão fácil mas), usando o browser. Hoje em dia ele roda legal
		onde eu trabalho, e espero que possa ser útil para vocês também. 
		
	2 - O que eu preciso para rodar o PHPReports ?

		Você precisa de um servidor Apache com suporte PHP, compilado com
		suporte XML/XSLT. Eu uso a lib Sablotron para isso
		(http://www.gingerall.com/charlie/ga/xml/p_sab.xml), e todos os exemplos
		são baseados nela.

	3 - Tem que pagar para usar ?
		Não, não, não. Está sob a GPL, e você não precisa pagar. Apenas siga
		as regras da GPL e todo mundo fica feliz. Eu realmente estava precisando
		de algum jeito de contribuir para a comunidade open source, e espero que
		isso seja apenas o começo. Se você realmente gostou do PHPReports e quer
		fazer algum tipo de doação ou coisa do tipo, você pode ver minha lista de
		desejos (wish list) na http://www.amazon.com. Apenas procure por 
		Eustáquio Rangel lá. :-)
		
	4 - Me conte como funciona
	
		Eu ouvi uma vez um professor muito sábio dizer que "o propósito de uma
		boa documentação é que você não precisa do autor grampeado nela, na sua
		biblioteca". Eu vou tentar fazer o melhor que eu posso para fazer isso
		valer, então vamos lá.
		Um relatório, no PHPReports ou outro programa que mexe com isso, sempre
		tem algumas divisões. Eu as chamo assim:

		- a camada do documento
		- a camada da página
		- a camada de agrupamento
		
		Tem apenas uma camada de documento, uma camada de página (você pode
		ter um monte de páginas, mas apenas uma camada para configurar) e 
		algumas camadas de grupos.
		Todas essas camadas coletam informação sobre os dados do seu relatório,
		como o número de linhas, estatísticas sobre os campos e por aí vai.
		A camada do documento armazena TODAS essas estatísticas, e armazena até
		que o relatório acabe.
		A camada da página armazena-as até que a página acabe, e as zera lá.
		A camada do grupo armazena-as até o fim do grupo, deixe-me traduzir 
		grupo aqui como dados definidos por uma expressão de quebra, que pode
		ser qualquer um dos campos contidos no seu conjunto de dados.
		Cada camada tem seu próprio cabeçalho (header) e rodapé (footer). A 
		camada do grupo tem uma divisão a mais onde mostra os dados. Se você tem
		mais que um grupo (mesmo se você tiver um relatório bem simples, você tem
		que adicionar um grupo para tratar suas informações), o grupo mais interno
		vai lhe mostrar os dados, o outro pode até lhe mostrar também, mas é sua
		escolha. Deixe-me tentar desenhar a coisa toda aqui:

	4.1 - Estrutura do relatório
		
		+----------------------------------+
		| DOCUMENT_LAYER                   |
		+----------------------------------+
		| HEADER                           |
		|                                  |
		| +------------------------------+ |
		| | PAGE_LAYER                   | |
		| +------------------------------+ |
		| | HEADER                       | |
		| |                              | |
		| | +--------------------------+ | |
		| | | GROUP LAYER              | | |
		| | | break expression A       | | |
		| | +--------------------------+ | |
		| | | HEADER                   | | |
		| | | FIELDS                   | | |
		| | |                          | | |
		| | | +----------------------+ | | |
		| | | | GROUP LAYER          | | | |
		| | | | break expression A,B | | | |
		| | | +----------------------+ | | |
		| | | | HEADER               | | | |
		| | | | FIELDS               | | | |
		| | | | FOOTER               | | | |
		| | | +----------------------+ | | |
		| | | FOOTER                   | | |
		| | |                          | | |
		| | +--------------------------+ | |
		| |                              | |
		| | FOOTER                       | |
		| +------------------------------+ |
		|                                  |
		| FOOTER                           |
		+----------------------------------+
		
		Então, documento (document) contém a página (page), página contém grupos (groups), e um
		grupo pode conter outro grupo.
		Uma regra nesse caso é que a expressão de quebra do grupo interno tem que conter a expressão
		de quebra do grupo acima. No exemplo, o primeiro grupo quebra quando A muda, e o segundo 
		grupo muda quando A e B mudam. Quando isso acontece, é disparado um evento que notifica que
		o grupo precisa imprimir seu rodapé e cabeçalho, e todos os outros grupos relacionados são
		notificados também, para fazer o que precisa ser feito.
		
	5 - Um exemplo simples

		Ok, vamos supor que você tem a seguinte tabela no seu banco de dados (não é um bom 
		desenho de tabela esse, mas é apenas para o exemplo):

		SalesLog
		ID       NUMBER 5
		NAME     CHAR   50
		CITY	   CHAR   50
		PRODUCT  CHAR   50
		VALUE		NUMBER 15,5

		Se você fizer essa consulta:
		
		select * from SalesLog order by ID

		você tem:

		1 - Eustaquio Rangel - Sao Jose do Rio Preto, SP - Book: Linux Programming Guide     - 25.00
		1 - Eustaquio Rangel - Sao Jose do Rio Preto, SP - Book: Design Patterns             - 35.00
		2 - Ana Carolina     - Sao Jose do Rio Preto, SP - Book: Photoshop 7.0               - 22.50
		3 - Andre Kada       - Sao Paulo, SP             - CD: Kreator - Violent Revolutions - 15.00

		*** DICA ÚTIL ***
		Para mais exemplos, inclusive um passo-a-passo, visite o website (http//phpreports.sourceforge.net)
		com os arquivos incluídos aqui.

	5.1 - Layout do relatório
		
		Agora você precisa de um relatório agrupando seus dados por cidade (city), desse jeito:
		
		+---------------------------------------+----+
		| John Doe Enterprises                  |////+--- camada do documento
		| Sales Report                          |////|
		+------+--------------------------------+----+
		| city | <city goes here>               |\\\\|
		+------+-+------+-------------+---------+\\\\|
		| id   | name   | product     | $       |\\\\|
		+------+--------+-------------+---------+\\\\+--- camada do grupo
		| <id> | <name> |	<product>	| <value> |\\\\|
		+------+--------+-------------+---------+\\\\|
		|                       total | <total> |\\\\|
		+-----------------------------+---------+----+ 
		|                  page total | <total> |////+--- camada da página
		+-----------------------------+---------+----+
		|                report total | <total> |\\\\+--- camada do documento (de novo)
		+-----------------------------+---------+----+

		A primeira coisa que você precisa pensar é fazer seu layout de relatório como
		se fosse uma tabela HTML (para ser honesto, É uma tabela HTML), então para o
		relatório acima temos uma tabela com 4 colunas e 8 linhas.

	5.2 - Código PHP
		
		Agora vamos ver o código PHP para consultar no seu banco de dados seus dados e
		fazer o relatório:	

		<?php
			include 'PHPReportMaker.php';
			$sql  = "select ID,NAME,CITY,PRODUCT,VALUE from SalesLog order by ID";
			$parm = Array();
			makeReport( "sales.xml", "PHPReport.xsl", "scott", "tiger", "connection", "databaseinterface", $sql, $parm );
		?>

		A função makeReport é uma unica função PHP que você precisa trabalhar. Vamos dar uma 
		olhada nos parametros dela, acima:
				
			1  - "sales.xml" - uma string com o arquivo de layout
			2  - "PHPReports.xsl" - o arquivo XSLT usado para converter o XML em código PHP
			3  - "scott" - uma string com o nome de usuário do banco de dados
			4  - "tiger" - uma string com a senha do banco de dados
			5  - "connection"- a conexão com o banco de dados
			6  - "databaseinterface" - você precisa especificar qual banco de dados você está conectando,
			     por exemplo, "oracle".
			7  - $sql - uma string com a query SQL
			8  - $parm - um array de parametros - limitado a 5 parametros

		Se você achar que tem muitos parametros na função makeReport (algumas vezes eu penso assim também),
		tem uma classe que pode nos ajudar com isso. Seu nome é PHPReportMaker e usando-a no exemplo acima
		ficaria assim:

		<?php
			include 'PHPReportMaker.php';
			$sql  = "select ID,NAME,CITY,PRODUCT,VALUE from SalesLog order by ID";
			$oRpt	= new PHPReportMaker();
			
			$oRpt->setXML("sales.xml");
			$oRpt->setUser("scott");
			$oRpt->setPassword("tiger");
			$oRpt->setConnection("connection");
			$oRpt->setDatabaseInterface("databaseinterface");
			$oRpt->setSQL($sql);
			$oRpt->run();
		?>

		Você percebeu que não usamos o array de parametros e o XSLT? A classe tem alguns valores
		default (para ser honesto, apenas o parametro é um Array() como default, o processador
		XSLT é sempre "PHPReport.xsl" e o resto dos parametros são todos nulos e não vão funcionar
		se você os deixar desse jeito ehehe) e - para parametros não obrigatórios - podemos rodar
		desse jeito. Algumas vezes é bem mais fácil e legível usar essa classe do que a função.
		Preste atenção especialmente no arquivo XSLT - se ele não está no diretório corrente, 
		não vai funcionar e você terá que mostrar onde ele está. Então você precisará de algo como
		$oRpt->setXSLT(<meupathcompletodoarquivoXSLT>) também.

		Os parametros da makeReports são:

		1  - string com o path do arquivo de layout XML *OBRIGATÓRIO*
		2  - string com o path do arquivo XSTL usado na transformação *OBRIGATÓRIO*
		3  - string com o nome do usuário do banco de dados *OBRIGATÓRIO*
		4  - string com a senha do banco de dados *OBRIGATÓRIO*
		5  - string com o nome da conexão do banco de dados - por ex. no Oracle, um nome no
		     arquivo TNSNAMES.ORA *OBRIGATÓRIO*
		6  - string com a interface do banco de dados (leia sobre isso abaixo) *OBRIGATÓRIO*
		7  - string com sua query SQL *OBRIGATÓRIO*
		8  - Array com parametros
		9  - string com o nome do banco de dados que você deseja usar 
		10 - string com o arquivo de saída do código PHP - as classes geradas com XML -> XSLT 
		     para rodar seu relatório
		11 - string com o path do arquivo HTML resultante - quando esse parametro não é null,
		     o arquivo vai ser criado e nenhum output vai ser feito quando você rodar seu 
			  relatório, mas isso é útil quando você quer fazer outro tratamento antes
			  de mostrar o relatório na tela - por ex. eu uso isso quando eu quero que os 
			  usuários abram o relatório em uma nova página quando desejarem, então eu coloco
			  algum nome temporário aqui e faço um link dentro de um script Javascript para 
			  abri-lo.
		12 - boolean - se verdadeiro, PHPReports vai lhe dar uma breve descrição do seu 
		     relatório, depois que o processar - aí você pode ver como o PHPReports está 
			  "vendo" seu arquivo de layout XML. 
			  
		*** AVISO DE SEGURANÇA ***
		
		Se você especificar um arquivo PHP para ser criado com o parametro 10, você *DEVE* 
		apagá-lo depois do uso, por que ele mantém o usuário e senha do banco de dados
		armazenados lá. 
		Se você apenas usa o parametro 10 como null, o arquivo vai ser automaticamente apagado
		depois da saída do relatório. Use como não nulo para propósito de depuração.

		A classe PHPReportMaker tem os seguintes métodos:

		run()												- usada quando todos os parametros estão ok - roda o relatório.
		setXML(string)/getXML()						- seta/retorna o path do arquivo XML
		setXSLT(string)/getXSLT()					- seta/retorna o path do arquivo XSLT
		setUser(string)/getUser()					- seta/retorna o usuário do banco de dados
		setPassword(string)/getPassword()		- seta/retorna a senha do banco de dados
		setConnection(string)/getConnection()	- seta/retorna o nome da conexão
		setDatabaseInterface(string)/				- seta/retorna o nome da conexão com o banco de dados
		getDatabaseInterface()		
		setSQL(string)/getSQL()						- seta/retorna a string da consulta SQL
		setParameters(array)/getParameters()	- seta/retorna o array de parametros
		setDatabase(string)/getDatabase()		- seta/retorna o nome do banco de dados
		setPHPOutput(string)/getPHPOutput()		- seta/retorna o path de saída do código PHP
		setOutput(string)/getOutput()				- seta/retorna o path de saída HTML
		setDebug(boolean)/getDebug()				- ativa/desativa o recurso de debug

		Apenas para dar uma explicação rápida antes de ir para uma mais extensa, as interfaces
		do banco de dados são alguns arquivos com seus nomes começados com "db_". Por exemplo,
		tem um db_oracle.php que eu estou trabalhando agora. Dentro dele tem algumas funções 
		que disponibilizam meios de abrir a conexão com o banco de dados, rodar a query SQL
		e por aí vai. Desde um banco de dados usa funções diferentes (em PHP) um do outro,
		você pode especificar um jeito que vai suportar essa funcionalidade. Os parametros de
		usuário e a senha são usados para abrir a conexão especificada no parametro connection.
		Estou usando a interface do Oracle agora, e vou colocar algumas outras interfaces no
		projeto, se você fizer uma por favor me envie para ser incluida no projeto.
		

	5.3 - Arquivo de layout XML
			
		*** NOTA IMPORTANTE ***
		Desde a versão 0.0.8 eu inclui alguns arquivos XML de exemplo com o pacote - verifique o
		website para ver os exemplos.
		
		Agora, o layout do relatório em XML. Isso é especificado pelo parametro sales.xml, mas o que
		o sales.xml tem dentro? Se lembra da comparação com a tabela HTML: Então, precisamos de um
		documento XML *bem-formado* como aquele, com linhas e colunas. Mas com as três camadas do
		relatório definidas nele também !!! Vai se parecer com isso:
			
		(P.S.: o arquivo sales.xml incluído no pacote não é igual a esse - esse está aí apenas para exemplo)	

		<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
		<?xml-stylesheet type="text/xsl" href="PHPReport.xsl"?>
		<!DOCTYPE REPORT SYSTEM "PHPReport.dtd"> 
		
		<REPORT>
			<TITLE>Sales Report</TITLE>
			<PATH>phpreports/</PATH>
			<BACKGROUND_COLOR>#FFFFFF</BACKGROUND_COLOR>
			<CSS>johndoe.css</CSS>
			<DOCUMENT>
				<FOOTER>
					<ROW>
						<COL COLSPAN="3" TEXTCLASS="BOLD" ALIGN="RIGHT">report total</COL>
						<COL TYPE="EXPRESSION" TEXTCLASS="BOLD" ALIGN="RIGHT">$this->getSum( "VALUE" )</COL>
					</ROW>
				</FOOTER>
			</DOCUMENT>
			<PAGE SIZE="30">
				<HEADER>
					<ROW>
		            <COL COLSPAN="4" TEXTCLASS="BOLD">John Doe Enterprises</COL>
				   </ROW>
		         <ROW>
				      <COL COLSPAN="4" TEXTCLASS="BOLD">Sales Report</COL>
		         </ROW>
		      </HEADER>
				<FOOTER>
					<ROW>
				      <COL COLSPAN="3" TEXTCLASS="BOLD" ALIGN="RIGHT">page total</COL>
		            <COL TYPE="EXPRESSION" TEXTCLASS="BOLD" ALIGN="RIGHT">$this->getSum( "VALUE" )</COL>
			      </ROW>
				</FOOTER>
			</PAGE>
		   <GROUPS>
		      <GROUP NAME="CityBreak" EXPRESSION="CITY">
		         <HEADER>
		            <ROW>
		               <COL ALIGN="RIGHT">city:</COL>
		               <COL TYPE="EXPRESSION" COLSPAN="3" TEXTCLASS="BOLD">$header->getValue( "CITY" )</COL>
		              </ROW>
		            <ROW>
		               <COL>id</COL>
		               <COL>name</COL>
		               <COL>product</COL>
		               <COL>$</COL>
		            </ROW>
		         </HEADER>
		         <FIELDS>
		            <ROW>
		               <COL>ID</COL>
		               <COL>NAME</COL>
		               <COL VISIBLE="FALSE">CITY</COL>
		               <COL>PRODUCT</COL>
		               <COL ALIGN="RIGHT" NUMBERFORMATEX="2">VALUE</COL>
		            </ROW>
		         </FIELDS>
		         <FOOTER>
		            <ROW>
		               <COL ALIGN="RIGHT">total</COL>
		               <COL TYPE="EXPRESSION" COLSPAN="3" TEXTCLASS="BOLD" ALIGN="RIGHT" NUMBERFORMATEX="2">$this->getSum( "VALUE" )</COL>
		            </ROW>
		         </FOOTER>
		      </GROUP>
		   </GROUPS>
		</REPORT>
		
		Vamos dar uma olhada nele. Primeiro, nós temos três linhas de instruções XML
		sobre a versão, encoding e o arquivo DTD (vamos falar dele na próxima seção),
		e nosso elemento raiz, sempre definido pela tag REPORT. REPORT tem alguns elementos
		dentro dele, mas vamos ve-los mais tarde (nós temos elementos TITLE, PATH, BACKGROUND_COLOR
		e CSS definidos lá). Depois a tag DOCUMENT (se lembra?) com o FOOTER definido. FOOTER e
		HEADER e algumas outras tags, tem ROWs e COLs dentro delas.
		Depois da tag REPORT, temos o tag PAGE e a tag GROUPS, com tags GROUPs dentro dela.
		
		Você pode ter uma prévia de como seu relatório ficará, *sem* os dados,
		usando o arquivo PHPReportPreview.php. Apenas aponte seu browser para o arquivo,
		usando um parametro "xml" com o path completo do seu arquivo XML de layout, por ex:

		http://localhost/phpreports/PHPReportPreview.php?xml=sales6.xml

		Você realmente precisa especificar o path completo do arquivo XML e *deve* rodar o
		PHPReportPreview no mesmo diretório onde está localizado o arquivo PHPReportPreview.xsl.
		Claro que você pode mudar esse comportamento no código do PHPReportPreview.php, é realmente
		bem fácil fazer isso. :-)
	
	6 - Arquivo DTD
		
		Vamos dar uma olhada mais de perto no arquivo PHPReports.dtd (se você não sabe o que diabos
		é tags XML, um arquivo DTD e coisas do tipo, procure na web sobre algum tutorial fácil e 
		rápido, será melhor para entender como as coisas funcionam por aqui, http
		http://www.w3schools.com/xml/ é uma boa escolha):

		<?xml version="1.0" encoding="ISO-8859-1"?>
		<!ELEMENT REPORT (TITLE?,PATH?,BACKGROUND_COLOR?,BACKGROUND_IMAGE?,CSS?,SQL?,DOCUMENT?,PAGE?,GROUPS?)>
		<!ATTLIST REPORT MARGINWIDTH CDATA #IMPLIED>
		<!ATTLIST REPORT MARGINHEIGHT CDATA #IMPLIED>
		<!ELEMENT TITLE (#PCDATA)> 
		<!ELEMENT PATH (#PCDATA)> 
		<!ELEMENT BACKGROUND_COLOR (#PCDATA)> 
		<!ELEMENT BACKGROUND_IMAGE (#PCDATA)> 
		<!ELEMENT CSS (#PCDATA)> 
		<!ELEMENT SQL (#PCDATA)> 
		<!ELEMENT DOCUMENT (HEADER?,FOOTER?)>
		<!ELEMENT HEADER (ROW*)>
		<!ELEMENT FOOTER (ROW*)>
		<!ELEMENT ROW (COL*)>
		<!ELEMENT COL (LINK?)>
		<!ATTLIST COL TYPE           CDATA #IMPLIED>
		<!ATTLIST COL NUMBERFORMAT   CDATA #IMPLIED>
		<!ATTLIST COL NUMBERFORMATEX CDATA #IMPLIED>
		<!ATTLIST COL CELLCLASS      CDATA #IMPLIED>
		<!ATTLIST COL TEXTCLASS      CDATA #IMPLIED>
		<!ATTLIST COL ROWSPAN		  CDATA #IMPLIED>
		<!ATTLIST COL COLSPAN        CDATA #IMPLIED>
		<!ATTLIST COL WIDTH          CDATA #IMPLIED>
		<!ATTLIST COL HEIGHT         CDATA #IMPLIED>
		<!ATTLIST COL ALIGN          CDATA #IMPLIED>
		<!ATTLIST COL VALIGN         CDATA #IMPLIED>
		<!ATTLIST COL VISIBLE        CDATA #IMPLIED>
		<!ATTLIST COL SUPPRESS       CDATA #IMPLIED>
		<!ELEMENT PAGE (HEADER?,FOOTER?)>
		<!ATTLIST PAGE SIZE        CDATA #IMPLIED>
		<!ATTLIST PAGE WIDTH       CDATA #IMPLIED>
		<!ATTLIST PAGE HEIGHT      CDATA #IMPLIED>
		<!ATTLIST PAGE CELLPADDING CDATA #IMPLIED>
		<!ATTLIST PAGE CELLSPACING CDATA #IMPLIED>
		<!ATTLIST PAGE BORDER      CDATA #IMPLIED>
		<!ATTLIST PAGE ALIGN       CDATA #IMPLIED>
		<!ELEMENT GROUPS (GROUP+)>
		<!ELEMENT GROUP (HEADER?,FIELDS?,FOOTER?,GROUP*)>
		<!ATTLIST GROUP NAME CDATA #REQUIRED>
		<!ATTLIST GROUP EXPRESSION CDATA #IMPLIED>
		<!ATTLIST GROUP PAGEBREAK CDATA #IMPLIED>
		<!ELEMENT FIELDS (ROW?)>
		<!ELEMENT LINK (#PCDATA)>
		<!ATTLIST LINK TYPE   CDATA #REQUIRED>
		<!ATTLIST LINK TARGET CDATA #IMPLIED>
		<!ATTLIST LINK TITLE  CDATA #IMPLIED>
		<!ELEMENT XHTML (#PCDATA)>

	6.1 - Elemento REPORT

		Elementos internos:
		
		TITLE					- o título HTML que vai aparecer no título da janela.
		PATH					- o path onde as classes do PHPReports estão. 
								  outra coisa que você deve usar é uma barra final (/)
								  no path (ex. phpreports/). é também uma boa idéia
								  colocar o conteúdo do pacote tar do PHPReports em um
								  diretório sem outras classes, apenas por questão de
								  organização. :-) você pode também alterar o include_path
								  no PHP para arrumar onde as classes do PHPReports estão
								  e não usar essa opção.
		BACKGROUND_COLOR	- cor de fundo do relatório
		BACKGROUND_IMAGE	- imagem de fundo do relatório
		CSS					- path do arquivo CSS que você quer usar no seu relatório
		SQL					- você pode escrever a query SQL aqui se assim desejar
		DOCUMENT				- a camada do documento
		PAGE					- a camada da página
		GROUPS				- o elemento GROUPS (não a camada do grupo!)

		Atributos:
		
		MARGINWIDTH			- comprimento da margem, em pixeis
		MARGINHEIGHT		- altura da margem, em pixeis

	6.2 - Elemento COL		

		Elementos internos:

		LINK - Elemento LINK (veja 6.10)

		Atributos:

		TYPE				- se você define como EXPRESSION, o PHPReports vai interpretar tudo que você por
							  no elemento COL como código PHP
		NUMBERFORMAT   - se é uma coluna numérica, você pode especificar aqui como a formatar, usando
		                 a formatação standard da linguagem C (por examplo, "%10.2f")
		NUMBERFORMATEX - formatação numérica extendida. use essa propriedade para formatar números com 
							  casas decimais e separador de milhares. coloque o número de casas decimais
							  no valor da propriedade. se lembre de usar setLocale para o locale que você quiser.							
		CELLCLASS		- especifique aqui a classe CSS que a célula vai usar
		TEXTCLASS		- especifique aqui a classe CSS que a coluna de texto vai usar										  
		ROWSPAN			- quantas linhas essa célula vai usar
		COLSPAN			- quantas colunas essa célula vai usar
		WIDTH				- a comprimento da célula
		HEIGHT			- a altura da célula
		ALIGN				- alinhamento horizontal da célula
		VALIGN			- alinhamento vertical da célula
		VISIBLE			- se FALSE, essa coluna não será visível quando estiver na camada do grupo
		SUPPRESS			- se TRUE, não mostra valores repetidos na camada do grupo

	6.3 - Elemento ROW
	
		Elementos internos:
		
		COL - Elemento COL (veja 6.2)

	6.4 - Elemento HEADER
	
		Elementos internos:
		
		ROW - Elemento ROW (veja 6.3)		

	6.5 - Elemento FOOTER
	
		Elementos internos:
		
		ROW - Elemento ROW (veja 6.3)		

	6.6 - Elemento PAGE
	
		Elementos internos:
		
		HEADER - Elemento HEADER (veja 6.4)
		FOOTER - Elemento FOOTER (veja 6.5)

		Atributos:

		SIZE        - o número de linhas que essa página vai ter
		WIDTH       - comprimento da página, em pixeis
		HEIGHT      - altura da página, em pixeis
		CELLPADDING	- padding interno da célula (o mesmo que HTML TABLE CELLPADDING)
		CELLSPACING - espaçamento interno da célula (o mesmo que HTML TABLE CELLSPACING)
		BORDER		- a borda da página entre as linhas e colunas, você pode colocar ela maior
						  que 0 para ver como sua tabela está ficando
		ALIGN			- o alinhamento da página na janela do browser
								  
	6.7 - Elemento FIELD 
	
		Elementos internos:
		
		ROW - Elemento ROW (veja 6.3)
		
	6.8 - Elemento GROUP
	
		Elementos internos:
		
		HEADER - Elemento HEADER (veja 6.4)
		FIELDS - Elemento FIELD (veja 6.7)
		FOOTER - Elemento FOOTER (veja 6.5)
		GROUP  - Elemento GROUP (esse aqui! um grupo pode conter outro grupo)

		Atributos:

		NAME       - nome do grupo, será usado para criar a classe com esse nome
		EXPRESSION - o nome do campo onde a expressão de quebra do grupo será baseada, 
		             quero dizer, quando esse campo mudar, vai ser disparado um evento de 
						 quebra no grupo
		PAGEBREAK  - se YES, toda vez que o grupo quebrar vai gerar uma quebra também da 
		             página
		
	6.9 - Elemento GROUPS
	
		Elementos internos:
		
		GROUP - Elemento GROUP (veja 6.8)

	6.10 - Elemento LINK

		Atributos:

		TYPE   - STATIC para links estaticos, ou seja, que não mudam ou
		         DYNAMIC para links que mudam com os valores do campo da consulta SQL.
		TARGET - frame onde o link vai abrir
		TITLE	 - texto da tooltip do mouse over		 

	6.11 - Elemento XHTML

		Elementos internos:
		
		Qualquer elemento XHTML que você queira.		

	7 - Validando seu documento

		Você pode usar o RXP (http://www.cogsci.ed.ac.uk/~richard/rxp.html) para validar seu
		arquivo XML, SEMPRE ANTES de usá-lo no browser (acredite, é uma boa idéia). 
		A sintaxe é assim:

		rxp -V -o 0 <file.xml>

	8 - Lista de arquivos
	
		db_mysql.php         - MySQL interface
		db_oracle.php        - Oracle interface
		db_interbase.php     - Interbase interface
		db_mssql.php		   - Microsoft SQL Server interface
		db_adodb.php			- ADODB interface (obrigado Aztek!)
		PHPRepoDoc.php	      - objeto da camada do documento
		PHPRepoField.php     - objeto do campo do banco de dados
		PHPRepoGroup.php     - objeto da camada do grupo
		PHPRepoPage.php      - objeto da camada da página
		PHPRepoRow.php       - objeto para linha do banco de dados
		PHPReport.dtd        - arquivo de validação XML
		PHPReportMaker.php   - a função/classe usada para fazer os relatórios
		phpreports.css       - arquivo de estilo
		PHPReport.xsl        - arquivo de transformação XSLT
		PHPReportCol.xsl     - arquivo de transformação XSLT 
		PHPReportDoc.xsl     - arquivo de transformação XSLT 
		PHPReportField.xsl   - arquivo de transformação XSLT 
		PHPReportGroup.xsl   - arquivo de transformação XSLT 
		PHPReportPage.xsl    - arquivo de transformação XSLT 
		PHPReportTable.xsl   - arquivo de transformação XSLT 
		PHPReportXHTML.xsl   - arquivo de transformação XSLT 
		sales.php				- arquivo de exemplo PHP
		sales7.php				- arquivo de exemplo PHP
		sales.xml            - arquivo de exemplo XML														
		sales2.xml           - arquivo de exemplo XML														
		sales3.xml           - arquivo de exemplo XML														
		sales3b.xml          - arquivo de exemplo XML														
		sales4.xml           - arquivo de exemplo XML														
		sales5.xml           - arquivo de exemplo XML														
		sales6.xml           - arquivo de exemplo XML														
		sales7.xml           - arquivo de exemplo XML														
		sales8.xml				- arquivo de exemplo XML
		PHPReportPreview.xsl - arquivo de transformaçao para previa
		PHPReportPreview.php - codigo para usar o arquivo de previa XSLT
		README					- esse arquivo, porém em Inglês
		LEIAME					- esse arquivo

	9 - Considerações finais

		Sem considerações finais. :-) Teste as tags e atributos para ver qual 
		satisfaz suas necessidades, faça um monte de testes, eu acredito que 
		tudo deve rodar bem. Até mais !!!

	10 - Changelog
	
		11 de Agosto de 2002
		--------------------
		- reescrito código para manter as interfaces dos bancos de dados de um jeito fácil de lidar
		- adicionado o arquivo de interface do MySQL
		- mudanças feitas no arquivo XSLT
		- adicionado o path do arquivo XSLT na função makeReport
		- adicionado o parametro de banco de dados na função makeReport

		31 de Agosto de 2002
		--------------------
		- adicionada a interface para o m$ SQL Server
		- algumas correções feitas nesse documento

		02 de Setembro de 2002
		----------------------
		- adicionada a propriedade NUMBERFORMATEX, para formatar números com 
		  casas decimais e separador de milhares.

		10 de Setembro de 2002
		----------------------
		- CORREÇÃO DE BUGÃO: os valores processados não estavam indo para a 
		  camada do grupo, então você não poderia se referir a eles (sempre 
		  nulo). agora funciona.
		- adicionada uma referencia para os dados do header com a referencia
		  $header. agora você pode referenciar os dados do header usando
		  $oValue (argh!) ou $header (melhor). :-)		  

		11 de Setembro de 2002
		----------------------
		- adicionada a função getRowNum(), para retornar o número da linha na
		  camada da página.

		21 de Outubro de 2002
		---------------------
		- consertadas algumas coisas na documentação (agradecimentos à Remigijus Sajauka)

		27 de Dezembro de 2002
		----------------------
		- consertadas algumas coisas aqui na documentação novamente.

		23 de Janeiro de 2003
		---------------------
		- adicionado o parametro de saída HTML 
		- criada a classe PHPReportMaker
		- adicionada a seção FAQ aqui no arquivo LEIAME

		26 de Janeiro de 2003 (1 semana de férias! oba!)
		- modificações nos parametros - agora você pode os referenciar com uma chave
		  do array (se tiver alguma) ou da forma numérica (ainda baseado em 1, não 0)

		28 de Janeiro de 2003
		---------------------
		- BUGÃO! O MySQL retornava alguns campos numéricos como o sendo do tipo REAL,
		  e eu não havia percebido isso ainda. Agora está ok. Isso corrige o comportamento
		  de todas as funções de agrupamento (getSum(),getMax(),getMin()...) que verificam
		  o tipo do campo para processar o valor. minhas desculpas para o pessoal que está
		  usando o MySQL.
		- para fixar o bug acima, nós precisamos de um jeito de ver como o PHPReports está
		  vendo os tipos de dados, então eu fiz a função debug() - verifique os parametros
		  da makeReport acima - para depurar como o PHPReports está "vendo" nosso arquivo 
		  de layout XML e, nesse caso de bug, qual a string do tipo do campo que o banco de
		  dados está retornando, se lembre que apenas campos númericos são permitidos para
		  uso das funções de agrupamento.		  

		29 de Janeiro de 2003
		---------------------
		- todo o dia gasto escrevendo o novo site ... um monte de documentação, putz, cara,
		  eu odeio fazer isso eheheh. :-)
		- adicionados os arquivos de exemplos - XML, PHP e CSS. verifique no site 
		  (http://phpreports.sourceforge.net) como usá-los.
		- vou liberar a 0.0.8 hoje.		    
		  
		04 de Fevereiro de 2003
		-----------------------
		- criado o arquivo PHPReportPreview. você pode usá-lo para ter uma prévia de como
		  seu layout do relatório está ficando *antes* de rodar a query SQL no seu banco
		  de dados. isso pode salvar algum tempo e processamento de dados. apenas aponte
		  seu browser para o arquivo com o parametro "xml" com o path do seu arquivo XML
		  de layout. por ex:

		  http://localhost/phpreports/PHPReportPreview.php?xml=sales6.xml

			
		  você tem mesmo que especificar o caminho completo do arquivo XML e você *deve*
		  rodar o PHPReportPreview no mesmo diretório onde está localizado o arquivo 
		  PHPReportPreview.xsl. claro que você pode mudar esse comportamento no código do
		  PHPReportPreview.php, é realmente muito fácil fazer isso. :-)

		09 de Fevereiro de 2003
		-----------------------
		- traduzido o README para esse arquivo aqui, o LEIAME		  

		10 de Fevereiro de 2003
		-----------------------
		- alterado o modo de impressão de valores - se não tem valor no campo,
		  imprime um espaço em branco, para fazer a célula da tabela HTML
		  ficar "correta" (agradecimentos para Kenneth N. Flaxman pelo meu
		  primeiro patch!)
		- criados os parametros CELLCLASSEVEN e CELLCLASSODD - use os nos
		  fields para diferenciar linhas pares e ímpares (even=pares,odd=ímpares),
		  baseado no grupo corrente. você pode verificar o arquivo sales3b.xml para
		  um exemplo desse recurso.

		15 de Fevereiro de 2003
		-----------------------
		- adicionada a interface para o Interbase (obrigado ao Andre "Biriba"
		  <andre@appsistemas.com.br> pela sua paciencia testando a interface -
		  eu não tenho um banco Interbase para testes ehehehe).
	   - adicionado o elemento LINK para inserir um link HTML A HREF dentro
		  do elemento COL.	   

		22 de Fevereiro de 2003
		-----------------------
		- dividi o arquivo principal XSLT em arquivos menores - mais fácil de
		  gerenciar
		- adicionada a interface ADODB - muito obrigado, Aztek!
		  para a usar, coloque setDatabaseInterface("adodb") e
		  setConnection para algo como setConnection("mysql:localhost");
		- adicionado suporte para elementos XHTML no arquivo XML - atenção, 
		  são arquivos XHTML e não HTML, tem muito poucas diferenças entre
		  eles (os arquivos XHTML tem que ser bem formados), aprenda mais
		  em http://www.w3.org  			  

	11  - Indíce das funções PHP mais comuns nas classes do PHPReports

		Você pode usar algumas funções para retornar alguns valores dos 
		campos/grupos correntes:
	
			getValue("campo")		- retorna o valor corrente do campo
			getMin("campo")		- retorna o valor mínimo do campo no grupo corrente
			getMax("campo")		- retorna o valor máximo do campo no grupo corrente
			getSum("campo")		- retorna a soma dos valores do campo no grupo corrente
			getAvg("campo")		- retorna a média dos valores do campo no grupo corrente
			getRowCount()			- retorna a contagem de linhas do grupo corrente
			getParameter(indice)	- retorna o parametro na posição especificada (baseado em 1)
			getParameter("chave")- retorna o parametro na chave especificada

		Você deve usar essas funções com a referencia $this->. Por exemplo:
	
			$this->getSum("TOTAL");

		dentro do seu arquivo XML. A única exceção são os valores que você pega
		do elemento HEADER. Você deve usar a referencia $oValue-> aqui, por exemplo:
			
			$oValue->getValue("CITY");

		Se você está usando uma versão igual ou maior que a 0.0.5, você pode usar
		a referencia $header para fazer isso também (eu acho que desse jeito fica
		mais vísivel e limpo):
		
			$header->getValue("CITY");	

		*** IMPORTANTE ***

		Eu explico por que. PHPReports apenas processa os valores dos campos quando
		eles alcançam o elemento ROW no elemento GROUP. Quando estão no elemento 
		HEADER, os valores são passados lá para o objeto $header (antiga $oValue),
		mas ainda não foram processados para serem referenciados para referencia
		$this ainda.

		Você precisa entender isso a respeito dos valores do header ...

		Outra coisa que eu tenho que dizer que pode ser um pouco confusa é sobre
		a getParameter(). Quando você coloca os valores dos parametros no array
		que você usa na função makeReport, é baseado em 0. Mas quando você pega o
		parametro no arquivo XML, é baseado em 1. Eu acho que é meio estranho você 
		falar "pegue o parametro 0" então eu deixei desse jeito. Não sei se foi uma
		boa idéia, mas ao menos você pode dizer "pegue o primeiro parametro". :-)

		Em Janeiro de 2003 eu mudei esse único modo de referenciar os parametros com
		a possibilidade de referenciar usando as chaves do array também. Em minha 
		opinião é mais fácil de lidar assim ... por exemplo:

		No modo de referencia numérico:
		
		$parm		= Array();
		$parm[0]	= "SAO PAULO";
		$parm[1] = "RIO DE JANEIRO";
	
		e no arquivo XML	

		getParameter(1); <- retorna SAO PAULO - se lembre, baseado em 1, não 0
		getParameter(2); <- retorna RIO DE JANEIRO

		No modo de referencia de chave:

		$parm				= Array();
		$parm["from"]	= "SAO PAULO";
		$parm["to"]		= "RIO DE JANEIRO";

		e no arquivo XML

		getParameter("from");	// retorna SAO PAULO
		getParameter("to");		// retorna RIO DE JANEIRO
		
	12 - FAQ

		P: Como posso testar se a Sablotron está rodando legal?
		R: Faça um pequeno teste com o arquivo sales6.xml e com o PHPReportPreview.xsl,
		   rodando o sabcmd desse jeito:
			
			sabcmd PHPReportPreview.xsl sales6.xml test.html

			Isso deve retornar uma saída válida de HTML no arquivo test.html. Abra-o em
			seu browser para ver uma prévia do layout do seu relatório.

		P: Tive um erro rodando o relatório e toda a instalação está ok ...
		   um negócio do tipo Fatal error: Call to a member function on a non-object in 
		   blá blá blá ... o que está acontecendo?
		R: Verifique as letras maiúsculas e minúsculas dos campos na consulta SQL 
		   e no arquivo de layout XML - alguns bancos de dados precisam dos campos exatamente
		   iguais, maiúsculas e minúsculas.
	
		P: Não tenho saída de linhas de dados no relatório, nenhuma. O que está acontecendo?
		R: Verifique o parametro PAGE SIZE, se ele é muito curto você não verá seu relatório.
		
		P: Estou tendo alguns problemas com as classes do PHPReports - me dizem que não estão 
		   encontrando algumas classes para incluir.
		R: Tem um parametro PATH no elemento REPORT. Se usando-o seu problema não acabar, 
			remova o parametro PATH e adicione o PATH das classes do PHPReports no seu código PHP
			usando ini_set("<seu_diretório_do_phpreports>"). Eu acho que desse jeito é o melhor jeito. :-)
	
		P: Não consigo ver valores no cabeçalho (header).
		R: Use $header e não $this e verifique a explicação do elemento HEADER no arquivo LEIAME.
	
		P: As funções de agrupamento (getSum(),getMin()) não funcionam! Só retornam 0 ou nulo quando
		   são chamadas.
		R: Por favor useo método setDebug(true) e me envie o output por email - 
		   PHPReports vai mostrar lá como ele está vendo os tipos dos campos, e
		   desde que ele apenas processa campos numéricos, pode ser que o jeito que seu
		   banco de dados está retornando o tipo do campo não seja um dos tipos que eu
		   coloquei como numéricos. Você não precisa me enviar o relatório completo, só
		   a descrição. Ah, e me conte também que banco de dados você está usando.<br>