É comum aplicações web necessitarem de exportar dados para os utilizadores. O formato mais comum é o CSV, mas em aplicações mais robustas é necessário um sistema mais complexo, que permita criar relatórios com gráficos, tabelas e em que a disposição da informação se adapte às necessidades dos utilizadores.

Neste artigo apresentamos o TinyButStrong, que, em conjunto com o OpenTBS, permite criar relatórios OpenXML e OpenDocument em PHP.

  1. Dificuldades na edição de documentos em PHP e apresentação do TinyButStrong
  2. Criação do modelo do documento (odt, docx, ods, xlsx)
  3. Emitir o relatório (PHP)
  4. Detalhes acerca do TinyButStrong

Dificuldades na edição de documentos em PHP e apresentação do TinyButStrong

Em PHP, a criação de relatórios em que os utilizadores possam editar os modelos sempre foi um calcanhar de Aquiles. Noutras linguagens de programação, como C# ou Java, a criação e edição de relatórios é relativamente simples pela abundância e facilidade de integração com classes especificas para o efeito, coisa que não é possível em PHP por ser uma linguagem de script.

As soluções mais simples e mais usadas são a utilização de CSV ou documentos PDF que, pelo formato dos próprios documentos, não permitem que os utilizadores editem modelos dos documentos. Quando falo em editar, estou a referir-me à possibilidade do utilizador final atualizar informação que seja fixa e que essas alterações se reflitam nas próximas emissões do relatório.

A situação melhorou com a chegada, há alguns anos, do PHPExcel e, mais recentemente, do PHPWord. Contudo, na minha opinião, estas bibliotecas apenas servem para pequenos documentos, devido aos recursos que consomem e às funcionalidades que disponibilizam.

Para colmatar esta situação apresento neste artigo o TinyButStrong (também chamado TBS), um sistema de modelos baseado em XML e HTML que, em conjunto com o plugin OpenTBS, permite a criação e edição de documentos OpenXML (docx, xlsx) e OpenDocument (odt, ods).

A criação deste formato, inicialmente pela Microsoft, e agora definido num standard ECMA permite disponibilizar o código do documento e alterar esse código, como se fosse XML. Na realidade um ficheiro docx ou odt é apenas um ficheiro comprimido (em zip), com o código OpenXML. Ainda que haja um standard, convém perceber que existem alterações profundas entre o Microsoft OpenXML e o OpenDocument que podem ser vistas em pormenor nesta página (em inglês).

Posto isto, resta dizer que o TinyButStrong e o OpenTBS permitem manipular documentos OpenXML e OpenDocument e que as extensões suportadas, à data de escrita deste artigo, são odt, ods, odg, odf, odm, odp, ott, ots, otg, otp, docx, xlsx, xlsm, pptx.

2. Criação do modelo do documento (odt, docx, ods, xlsx)

Para efeitos de demonstração, criámos o modelo abaixo, no Microsoft Word 2013.

Criar documentos OpenXML e OpenDocument em PHP com OpenTBS images/18-create-openxml-opendocument-with-tbs-opentbs-in-php/275-report-template.png

No modelo indicamos as variáveis que devem ser substituídas quando o relatório é emitido, que no exemplo são record_id, created_at, fullname e birth_date. Nota que antes das variáveis existe sempre a designação block., porque o TBS trabalha com blocos de dados.

Para relatórios simples podes ter apenas um bloco, mas para documentos mais complexos os blocos são bastante úteis porque permitem segmentar a informação. Imaginando que queres criar um relatório com a informação de um filme, podes ter um bloco com a informação genérica (nome do filme, data de lançamento, classificação, realizador, …), outra com a informação dos atores (nome do ator, nacionalidade, idade, …) e outra com os comentários do filme (data do comentário, descrição, pontuação, autor).

3. Emitir o relatório (PHP)

O processamento do documento é relativamente simples. Seguindo a lógica dos blocos de informação, basta criar um array com a informação de cada bloco e fazer um merge com o documento.

// Incluir as classes TinyButStrong e OpenTBS
include_once('tbs_class.php');
include_once('tbs_plugin_opentbs.php');

// Cria uma nova instância do TBS e carrega o plugin OpenTBS
$tbs = new clsTinyButStrong;
$tbs->Plugin(TBS_INSTALL, OPENTBS_PLUGIN);

// A definição NoErr é útil em desenvolvimento, para apresentar todos os erros
$tbs->NoErr = false;

// Definimos o caminho do template do relatório.
// Neste caso estamos a usar docx, mas é possível usar odt, xlsx ou ods
$templatePath = 'report-template.docx';

// Carrega o template para a instância do TBS
$tbs->LoadTemplate($templatePath, OPENTBS_ALREADY_UTF8);

// Preenche um array dummy com os dados que queremos no documento final. Numa aplicação
// real, estes dados viriam de uma base de dados ou mecanismo de armazenamento (ou até
// do input do utilizador)
$blockInfo = [
    'record_id'  => '123',
    'created_at' => date('d-m-Y'),
    'fullname'   => 'Geekalicious',
    'birth_date' => '2015-01-01',
];

// Importante: o MergeBlock recebe um array de arrays
$dataToMerge = [
    $blockInfo
];

// Neste momento o TBS vai substituir as variáveis pelo conteúdo que estamos a enviar.
// De notar que é necessário definir o nome do bloco de dados.
// @see https://www.tinybutstrong.com/manual.php#php_mergeblock
$tbs->MergeBlock('b', $dataToMerge);

// Depois do template processado, o ficheiro é armazenado através do método Show
$processedPath = 'processed-document.docx';
$tbs->Show(OPENTBS_FILE, $processedPath);

O código contém os comentários que acredito serem suficientemente esclarecedores para que fiques com uma ideia de como funciona o sistema.

4. Detalhes acerca do TinyButStrong

Comecei a usar estas classes em 2011 e, desde então, não encontrei melhor mecanismo para criar relatórios em PHP. Ainda este ano (2015) voltei a pesquisar por novas soluções e continua sem existir uma solução melhor para criar documentos OpenXML e OpenDocument em PHP. Contudo, também têm as suas lacunas, entre as quais:

  • O manual podia ser mais legível e mais simples.
  • A curva de aprendizagem da linguagem do template e de todas as potencialidades das classes é grande.
  • O próprio código das classes merecia uma revisão (como exemplo, deveriam incluir o Composer).

No entanto, a flexibilidade destas classes é tal que posso afirmar que é, neste momento, a melhor forma para criar relatórios em PHP.

Deixo ainda o link para a demonstração online e uma demonstração de um modelo de carta, real e em produção:

Criar documentos OpenXML e OpenDocument em PHP com OpenTBS images/18-create-openxml-opendocument-with-tbs-opentbs-in-php/274-report-letter-template.png

No próximo artigo completamos a sequência de criação de documentos e vamos converter o documento OpenDocument para PDF.

Fica atento e, se tiveres alguma questão, fala connosco (vê o Sobre o Blog).