Agora precisamos de alguns grupos!
Vamos supor que você precisa agrupar por cidade. E precisa de uma linha com o nome da cidade no cabeçalho e a soma de todos os valores relativos àquela cidade no rodapé. É fácil, vamos ver o arquivo sales4.xml:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE REPORT SYSTEM "PHPReport.dtd">
<REPORT>
<TITLE>Sales Report</TITLE>
<BACKGROUND_COLOR>#FFFFFF</BACKGROUND_COLOR>
<CSS>phpreports.css</CSS>
<PAGE BORDER="1" SIZE="25" CELLSPACING="0" CELLPADDING="5" WIDTH="500">
<HEADER>
<ROW>
<COL COLSPAN="4" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD">John Doe Enterprises</COL>
</ROW>
<ROW>
<COL COLSPAN="4" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD">Sales Report</COL>
</ROW>
</HEADER>
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="PAGE_LAYER">page total</COL>
<COL ALIGN="LEFT" NUMBERFORMATEX="2" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
</PAGE>
<GROUPS>
<GROUP NAME="citygroup" EXPRESSION="city">
<HEADER>
<ROW>
<COL CELLCLASS="GROUP_LAYER">city:</COL>
<COL CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" TYPE="EXPRESSION" COLSPAN="3">$header->getValue("city")</COL>
</ROW>
<ROW>
<COL CELLCLASS="GROUP_LAYER">id</COL>
<COL CELLCLASS="GROUP_LAYER">name</COL>
<COL CELLCLASS="GROUP_LAYER">product</COL>
<COL CELLCLASS="GROUP_LAYER">$</COL>
</ROW>
</HEADER>
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="GROUP_LAYER">total</COL>
<COL ALIGN="LEFT" CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" NUMBERFORMATEX="2" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
<FIELDS>
<ROW>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">id</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">name</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">product</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER" NUMBERFORMATEX="2">value</COL>
</ROW>
</FIELDS>
</GROUP>
</GROUPS>
</REPORT>
E agora se parece com isso:Agora estamos conversando! :-) Nosso primeiro grupo coloca toda a informação sobre o campo city em um bloco e criou um cabeçalho e um rodapé para isso, com o campo value (valor) nele. Por favor note que eu alterei o nome do grupo (<GROUP NAME="citygroup">) e usei uma expressão para fazer ele quebrar (obrigatória em grupos que quebram - <GROUP NAME="citygroup" EXPRESSION="city">).
A expressão que você usa no atributo do elemento do grupo é um dos campos do relatório. Quando ele muda, automaticamente o grupo vai imprimir seu rodapé (se ele tiver um). Aí você pode usar uma das funções de agrupamento para pegar seus resultados. A referência $this-> vai apontar para o grupo corrente.
Note que eu também usei um atributo NUMBERFORMATEX="2" para arredondar os valores dos campos para duas casas decimais.
"Ok, agora eu quero fazer um sub-grupo, para cada cliente dentro de cada cidade" ... sem problemas"
Aqui está o arquivo sales5.xml:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE REPORT SYSTEM "PHPReport.dtd">
<REPORT>
<TITLE>Sales Report</TITLE>
<BACKGROUND_COLOR>#FFFFFF</BACKGROUND_COLOR>
<CSS>phpreports.css</CSS>
<PAGE BORDER="1" SIZE="25" CELLSPACING="0" CELLPADDING="5" WIDTH="500">
<HEADER>
<ROW>
<COL COLSPAN="4" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD">John Doe Enterprises</COL>
</ROW>
<ROW>
<COL COLSPAN="4" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD">Sales Report</COL>
</ROW>
</HEADER>
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="PAGE_LAYER">page total</COL>
<COL ALIGN="LEFT" NUMBERFORMATEX="2" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
</PAGE>
<GROUPS>
<GROUP NAME="citygroup" EXPRESSION="city">
<HEADER>
<ROW>
<COL CELLCLASS="GROUP_LAYER">city:</COL>
<COL CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" TYPE="EXPRESSION" COLSPAN="3">$header->getValue("city")</COL>
</ROW>
<ROW>
<COL CELLCLASS="GROUP_LAYER">id</COL>
<COL CELLCLASS="GROUP_LAYER">name</COL>
<COL CELLCLASS="GROUP_LAYER">product</COL>
<COL CELLCLASS="GROUP_LAYER">$</COL>
</ROW>
</HEADER>
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="GROUP_LAYER">city total</COL>
<COL ALIGN="LEFT" CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" NUMBERFORMATEX="2" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
<GROUP NAME="customergroup" EXPRESSION="name">
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="GROUP_LAYER">customer total</COL>
<COL ALIGN="LEFT" CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" NUMBERFORMATEX="2" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
<FIELDS>
<ROW>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">id</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">name</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">product</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER" NUMBERFORMATEX="2">value</COL>
</ROW>
</FIELDS>
</GROUP>
</GROUP>
</GROUPS>
</REPORT>
E agora se parece com isso:Tudo que você precisa fazer é inserir um elemento GROUP dentro de outro elemento GROUP. Nesse caso temos dois grupos, citygroup e customergroup. O citygroup é o grupo principal, o grupo que tem "filhos" mas não "pais" (o customergroup é um "filho") e o customergroup é o grupo de detalhe, o grupo onde os valores vão aparecer. Dê uma olhada no arquivo DTD para ver como os grupos são organizados.
Então, acabou e ... ESPERE!!! Onde está o total do relatório???
Putz, esqueci dele, mas não se preocupe, é fácil também !!!
Deixe-me mencionar que os elementos do DOCUMENT, HEADER (cabeçalho do documento) e FOOTER (rodapé) são separados do resto do layout da página, quero dizer, como eles apenas recebem os valores depois que processam todas as páginas, são tabelas diferentes (lembre-se: a página inteira é uma tabela) depois da tabela da página. Para deixar mais claro: eles não respeitam a largura das colunas da página, por que estão fora das colunas da página. Então se você precisar fazer os elementos do DOCUMENT, HEADER e FOOTER, ficarem alinhados com o resto da página, calcule e use o atributo WIDTH em todos os seus elementos COL.
Então lá vamos nós, com o arquivo sales6.xml:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE REPORT SYSTEM "PHPReport.dtd">
<REPORT>
<TITLE>Sales Report</TITLE>
<BACKGROUND_COLOR>#FFFFFF</BACKGROUND_COLOR>
<CSS>phpreports.css</CSS>
<DOCUMENT>
<FOOTER BORDER="1" CELLSPACING="0" CELLPADDING="5" WIDTH="500">
<ROW>
<COL ALIGN="RIGHT" CELLCLASS="DOCUMENT_LAYER" WIDTH="430">report total</COL>
<COL ALIGN="LEFT" CELLCLASS="DOCUMENT_LAYER" TEXTCLASS="BOLD" NUMBERFORMATEX="2" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
</DOCUMENT>
<PAGE BORDER="1" SIZE="25" CELLSPACING="0" CELLPADDING="5" WIDTH="500">
<HEADER>
<ROW>
<COL COLSPAN="4" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD">John Doe Enterprises</COL>
</ROW>
<ROW>
<COL COLSPAN="4" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD">Sales Report</COL>
</ROW>
</HEADER>
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="PAGE_LAYER">page total</COL>
<COL ALIGN="LEFT" NUMBERFORMATEX="2" CELLCLASS="PAGE_LAYER" TEXTCLASS="BOLD" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
</PAGE>
<GROUPS>
<GROUP NAME="citygroup" EXPRESSION="city">
<HEADER>
<ROW>
<COL CELLCLASS="GROUP_LAYER">city:</COL>
<COL CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" TYPE="EXPRESSION" COLSPAN="3">$header->getValue("city")</COL>
</ROW>
<ROW>
<COL CELLCLASS="GROUP_LAYER">id</COL>
<COL CELLCLASS="GROUP_LAYER">name</COL>
<COL CELLCLASS="GROUP_LAYER">product</COL>
<COL CELLCLASS="GROUP_LAYER">$</COL>
</ROW>
</HEADER>
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="GROUP_LAYER">city total</COL>
<COL ALIGN="LEFT" CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" NUMBERFORMATEX="2" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
<GROUP NAME="customergroup" EXPRESSION="name">
<FOOTER>
<ROW>
<COL ALIGN="RIGHT" COLSPAN="3" CELLCLASS="GROUP_LAYER">customer total</COL>
<COL ALIGN="LEFT" CELLCLASS="GROUP_LAYER" TEXTCLASS="BOLD" NUMBERFORMATEX="2" TYPE="EXPRESSION">$this->getSum("value")</COL>
</ROW>
</FOOTER>
<FIELDS>
<ROW>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">id</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">name</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER">product</COL>
<COL TYPE="FIELD" CELLCLASS="GROUP_LAYER" NUMBERFORMATEX="2">value</COL>
</ROW>
</FIELDS>
</GROUP>
</GROUP>
</GROUPS>
</REPORT>
Agora se parece com isso: