03 fev 2014
Biblioteca mPDF para gerar relatórios em PHP
Neste artigo vamos falar sobre gerar relatórios em PDF com a biblioteca mPDF no PHP, precisei dessa funcionalidade a um tempo atrás e sofri um pouco até encontrar essa biblioteca mPDF.
Todos sabem que o PHP não possui uma IDE para geração de relatórios ainda, até existem projetos interessantes como é o caso da biblioteca PHPJasperReport que pode ser utilizada em conjunto com a IDE iReport (excelente editor de relatórios em JAVA), mas essa biblioteca não contém diversas funcionalidades de quebra de relatório, sub-relatórios, imagens e etc., além do projeto estar parado.
Outra opção é a biblioteca fpdf, muito conhecida pelos desenvolvedores PHP, onde podemos construir os relatórios literalmente na “unha”. Essa biblioteca trabalha orientada a objetos então toda a parte de construção de linhas, customizações de cores, posicionamento do relatório com margens é feita utilizando métodos específicos da classe fpdf, mas além desse trabalho todo aparentemente o projeto está parado desde 2011. Iniciei meus relatórios com essa biblioteca, até cheguei a desenvolver um ou dois relatórios para o cliente, mas o layout, disposição dos dados e a complexidade de manutenção não me agradavam.
Biblioteca mPDF solução dos problemas!
Então pesquisando cheguei a “8º maravilha do mundo … rssrsr” a biblioteca mPDF. Essa biblioteca trabalha com a estrutura do relatório em HTML e a estilização com folhas de estilo CSS, com ela temos maior poder de customização no relatório. Basicamente você escreve um código HTML, exemplo uma tabela, estiliza ela com CSS e passa esses conteúdos para o objeto instanciado a partir da biblioteca mpdf, chamando os métodos adequados temos um PDF sendo exibido no navegador e com a opção de ser gravado na máquina do usuário.
Agora chega de conversa e vamos por a mão na massa, vou demonstrar como construir um relatório simples baseado em uma tabela para cadastro de clientes.
1 – Devemos efetuar download da biblioteca mPDF e copiá-lo para pasta raiz do projeto.
2 – Para organizar será construído uma classe reportCliente que extenda a classe mpdf, para isso devemos colocar um require_once() direcionando para os fontes da biblioteca mPDF e também será utilizado uma conexão com um banco de dados no MySQL, como já é de costume vamos usar essa classe de conexão postada em um artigo anterior.
Observação: Nesse artigo está sendo utilizado uma classe para gerar o relatório, mas nada impede que seja instanciado um objeto mpdf e através dele seja chamado os métodos necessários.
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
<?php require_once "conexao/conexao.php"; require_once "MPDF/mpdf.php"; class reportCliente extends mpdf{ // Atributos da classe private $pdo = null; private $pdf = null; private $css = null; private $titulo = null; /* * Construtor da classe * @param $css - Arquivo CSS * @param $titulo - Título do relatório */ public function __construct($css, $titulo) { $this->pdo = Conexao::getInstance(); $this->titulo = $titulo; $this->setarCSS($css); } /* * Método para setar o conteúdo do arquivo CSS para o atributo css * @param $file - Caminho para arquivo CSS */ public function setarCSS($file){ if (file_exists($file)): $this->css = file_get_contents($file); else: echo 'Arquivo inexistente!'; endif; } /* * Método para montar o Cabeçalho do relatório em PDF */ protected function getHeader(){ $data = date('j/m/Y'); $retorno = "<table class=\"tbl_header\" width=\"1000\"> <tr> <td align=\"left\">Biblioteca mPDF</td> <td align=\"right\">Gerado em: $data</td> </tr> </table>"; return $retorno; } /* * Método para montar o Rodapé do relatório em PDF */ protected function getFooter(){ $retorno = "<table class=\"tbl_footer\" width=\"1000\"> <tr> <td align=\"left\"><a href=''>devwilliam.blogspot.com</a></td> <td align=\"right\">Página: {PAGENO}</td> </tr> </table>"; return $retorno; } /* * Método para construir a tabela em HTML com todos os dados * Esse método também gera o conteúdo para o arquivo PDF */ private function getTabela(){ $color = false; $retorno = ""; $retorno .= "<h2 style=\"text-align:center\">{$this->titulo}</h2>"; $retorno .= "<table border='1' width='1000' align='center'> <tr class='header'> <th>Nome</td> <th>Telefone</td> <th>Idade</td> <th>Profissão</td> <th>E-mail</td> <th>Endereço</td> <th>Cidade</td> <th>Estado</td> </tr>"; $sql = "SELECT * FROM TAB_CLIENTE"; foreach ($this->pdo->query($sql) as $reg): $retorno .= ($color) ? "<tr>" : "<tr class=\"zebra\">"; $retorno .= "<td class='destaque'>{$reg['nome']}</td>"; $retorno .= "<td>{$reg['fone']}</td>"; $retorno .= "<td>{$reg['idade']}</td>"; $retorno .= "<td>{$reg['profissao']}</td>"; $retorno .= "<td>{$reg['email']}</td>"; $retorno .= "<td>{$reg['endereco']}</td>"; $retorno .= "<td>{$reg['cidade']}</td>"; $retorno .= "<td>{$reg['uf']}</td>"; $retorno .= "<tr>"; $color = !$color; endforeach; $retorno .= "</table>"; return $retorno; } /* * Método para construir o arquivo PDF */ public function BuildPDF(){ $this->pdf = new mPDF('utf-8', 'A4-L'); $this->pdf->WriteHTML($this->css, 1); $this->pdf->SetHTMLHeader($this->getHeader()); $this->pdf->SetHTMLFooter($this->getFooter()); $this->pdf->WriteHTML($this->getTabela()); } /* * Método para exibir o arquivo PDF * @param $name - Nome do arquivo se necessário grava-lo */ public function Exibir($name = null) { $this->pdf->Output($name, 'I'); } } |
Algumas observações sobre essa classe, claro que ela pode ser melhorada e modificada de acordo a necessidade do relatório, pode se ainda construir uma classe abstrata com algumas implementações para serem reaproveitadas nas classes descedentes. Explicação para cada método:
__construct($css, $titulo): Esse método recebe 2 parâmetros, o primeiro é caminho para o arquivo CSS e o segundo é o título que será exibido no topo do relatório. Observem que é chamado o método $this->setCSS() o mesmo será explicado adiante.
setarCSS($file): Esse método recebe como parâmetro o caminho do arquivo CSS, verifica se o mesmo existe e carrega o conteúdo do arquivo no atributo $css;
getHeader(): Esse método configura o cabeçalho do arquivo PDF, podemos colocar as informações que acharmos importantes, número de página, datas, nome de relatório, emissor e etc., tudo dentro de uma variável contendo código HTML e usando tabela para facilitar o alinhamento, posteriormente o método retorna essa variável.
getFooter(): Esse método é muito parecido com o getHeader(), ele configura o rodapé do arquivo PDF, podemos colocar as informações que acharmos importantes, número de página, datas, nome de relatório, emissor e etc., tudo dentro de uma variável contendo código HTML e usando tabela para facilitar o alinhamento, posteriormente o método retorna essa variável.
getTabela(): Esse método é quem realmente monta a tabela contendo os dados, nele é construído a estrutura da tabela HTML e adicionado o retorno do banco de dados, observem que foi executada uma consulta e posteriormente o array com os dados foi percorrido preenchendo a tabela. Idêntico quando construímos uma página com tabela, sempre atribuindo o código HTML para uma variável e no final o método retorna essa variável.
BuildPDF(): Esse método é responsável em setar alguns parâmetros de configuração como charset, tamanho da folha e passar o conteúdo HTML e CSS chamando os métodos acima para capturar o retorno e atribuir para os métodos herdados (WriteHTML(), SetHTMLHeader() e SetHTMLFooter()) da classe mpdf.
Exibir($name): Esse método recebe um parâmetro $name, que será o nome do arquivo PDF se o usuário decidir gravá-lo em disco, internamente é chamado o método herdado da classe mpdf Output() que recebe como parâmetro o nome do arquivo e a ação que deverá ser executada quando for chamado a exibição do relatório, abaixo as opções:
I – Envia o arquivo para ser exibido no navegador se o mesmo possuir o plugin Adobe instalado e salva com o nome passado como parâmetro se o usuário clicar em “Save as”.
D – Força um download com o nome do arquivo passado como parâmetro.
F – Salva em um diretório local com o nome passado como parâmetros (incluir o caminho do diretório).
S – Devolve o documento em forma de string.
3 – Criar folha de estilo CSS bem simples para ser utilizada na estilização do relatório:
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 |
/* Fonte para as tags table e h2 */ table, h2{ font-family: Arial; } /* Estilização para tag h2 */ h2{ color: blue; text-shadow: 2px darkgray; } /* Classe para o estilo do cabeçalho da Tabela */ .header{ background: yellowgreen; } /* Classe coloca a cor de fundo para zebrar as linhas */ .zebra{ background: lightgray; } /* Classe para destacar o conteúdo da coluna */ .destaque{ color: red; font-weight: bold; } |
Para finalizar segue abaixo a página index.php onde foi chamado a classe reportCliente, essa página foi construída com um form simples contendo apenas um botão submit. Esse form será submetido na mesma página e vai chamar a construção e exibição do relatório:
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 |
<?php // Require no script da classe reportCliente require_once "reportCliente.class.php"; /* * Verifica se é uma submissão, se for instância o objeto reportCliente * passa os parâmetros para o construtor, chama o método para construção do PDF * e manda exibi-lo no navegador. */ if(isset($_GET['submit'])): $report = new reportCliente("css/estilo.css", "Relatório de Clientes"); $report->BuildPDF(); $report->Exibir("Relatório de Clientes"); endif; ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Testando relatório com mPDF</title> </head> <body> <form action="" method="GET" target="_blank"> <input type="submit" value="Gerar relatório" name="submit"/> </form> </body> </html> |
Resultado no navegador:
Ao pressionar o botão “Gerar relatório” será aberta uma nova aba no navegador para exibir o relatório em PDF:
Link para baixar o arquivo Relatório de Clientes.pdf.
Nesse exemplo construí um relatório bem “carnavalesco” colocando umas cores, fundo verde e sombra no título, mas existem diversas possibilidades de customizações que podem ser feitas e o melhor de tudo isso, utilizando CSS o que pessoalmente achei uma maravilha.
Dica: Não abusem do CSS3, ele não está totalmente implementado pela biblioteca mPDF, tive uma experiência ruim quando fui testar meus relatórios no IE 9 tudo por causa de alguns estilos do CSS3.
Bom pessoal acessem a documentação da biblioteca mPDF, pois não apresentei nem 1% do poder dessa biblioteca, existem vários métodos e atributos interessantes e que podem ser explorados da melhor maneira possível.
Até a próxima …