Gerando arquivos PDF com PHP 

Escrito por Fabio Centenaro • Feb 1st, 2008 • Categoria: PHP, Programação

Introdução

Os arquivos PDF se transformaram ao longo do tempo em um padrão para troca de documentos. Desde relatórios até contratos, este formato tem sido usado em larga escala devido a sua portabilidade – é possível abrir arquivos deste tipo em qualquer sistema operacional – além de, geralmente, ser um arquivo pequeno. Isso sem falar que um arquivo PDF não pode ser modificado, garantindo, desta forma, que o arquivo irá sempre manter o mesmo conteúdo. Eu arriscaria dizer, ainda, que passa uma aparência mais profissional enviar um arquivo em formato PDF, ao invés de outros formatos, como DOC, por exemplo.

Neste artigo iremos conhecer os fundamentos da criação de um arquivo PDF utilizando a linguagem PHP. Para tal, será usada a biblioteca FPDF, responsável pela criação do arquivo. O download pode ser feito aqui.

Conhecendo as principais funções

Abaixo estão relacionadas as principais funções que serão utilizadas para a criação do arquivo, com a respectiva descrição.

SetFont - Define a fonte que será usada para imprimir o texto. É obrigatório setar ao menos uma vez a fonte que será utilizada no documento.

SetTitle - Define o título do documento.

SetSubject - Define o assunto do documento.

SetX - Define a abscissa da posição corrente. A grosso modo podemos dizer que informa a posição a partir da margem esquerda do documento.

SetY - Explicando de uma forma simples, indica a linha (posição vertical).

Cell - Imprime uma célula (área retangular) com bordas opcionais, cor de fundo e texto. O canto superior-esquerdo da célula corresponde à posição atual. O texto pode ser alinhado ou centralizado. Depois de chamada, a posição atual se move para a direita ou para a linha seguinte. É possível pôr um link no texto. Se a quebra de página automática está habilitada e a pilha for além do limite, uma quebra de página é feita antes da impressão.

Ln - Faz uma quebra de linha. A abscissa corrente volta para a margem esquerda e a ordenada é somada ao valor passado como parâmetro.

MultiCell - Este método permite imprimir um texto com quebras de linha. Podem ser automática (assim que o texto alcança a margem direita da célula) ou explícita (através do caracter n). Serão geradas tantas células quantas forem necessárias, uma abaixo da outra.

Image - Permite inserir uma imagem no documento. Os tipos permitidos são JPG e PNG.

AddPage - Acrescenta uma página ao documento.

PageNo - Informa a página atual.

AliasNbPages - Define um apelido para a impressão do número total de páginas.

Header e Footer - Estes métodos inserem automaticamente o cabeçalho e rodapé das páginas do documento. Porém, para utilizá-las, é necessário criar uma subclasse para sobrepor os métodos originais.

Output – Envia o documento para o destino informado. Pode-se abrir o arquivo no navegador, fazer o download ou mesmo salvar o arquivo no disco.

OBSERVAÇÃO:

Sempre que for necessário setar a posição X e Y, sete primeiro o Y e depois o X.

Criando nosso primeiro documento

Agora vamos ver como criar um arquivo simples, contendo algum texto e uma imagem.

<?

require_once(”fpdf/fpdf.php”);

$texto = “Os arquivos PDF se transformaram ao longo do tempo em um padrão para troca de documentos. Desde relatórios até contratos, este formato
tem sido usado em larga escala devido a sua portabilidade – é possível abrir arquivos deste tipo em qualquer sistema operacional – além de, geralmente, ser um arquivo pequeno.
Isso sem falar que um arquivo PDF não pode ser modificado, garantindo, desta forma, que o arquivo irá sempre manter o mesmo conteúdo. Eu arriscaria dizer, ainda, que passa uma
aparência mais profissional enviar um arquivo em formato PDF, ao invés de outros formatos, como DOC, por exemplo.”;

//defininfo a fonte !
define(’FPDF_FONTPATH’,'fpdf/font/’);

//instancia a classe
//uso: FPDF(orientacao – retrato ou paisagem), unidade de medida, tamanho do papel)
$pdf = new FPDF(”P”,”mm”,”A4″);

//define a fonte a ser usada
//uso: SetFont(nome da fonte, estilo (branco = normal, b = negrito, i = italico, u = sublinhado), tamanho da fonte)
$pdf->SetFont(’arial’,”,10);

//define o titulo
$pdf->SetTitle(”Criando nosso primeiro arquivo PDF !”);

// seta a posicao vertical e horizontal
$pdf->SetY(”-1″);

//assunto
$pdf->SetSubject(”Criação de arquivos PDF com PHP!”);

//escreve o texto
//uso: Cell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado)
$pdf->Cell(0,5,”Criando arquivos PDF com PHP”,0,0,’L');
$pdf->Cell(0,5,’http://fdweb.com.br’,0,1,’R');
$pdf->Cell(0,0,”,1,1,’L');
$pdf->Ln(8);

//Seta a fonte do texto do documento
$pdf->SetFont(’arial’,”,8);

// insere a imagem
//uso: Image(caminho, posicao X,posicao Y,altura, largura)
//$pdf->Image(”http://fdweb.com.br/downloads/logo.jpg”, $pdf->GetX(), $pdf->GetY(), 20, 20);
$pdf->Image(”logo.jpg”,10,30);

//posiciona horizontalmente
$pdf->SetY(”30″);
$pdf->SetX(”50″);

//Insere o texto do documento
//uso: MultiCell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado, J = justificado)
$pdf->MultiCell(0,5,$texto,0,”L”,0);

$pdf->Output(”arquivo pdf”,”I”);

?>

Este exemplo mostra como criar um arquivo simples, com texto e uma imagem.

Implementando cabeçalho e rodapé

Para que todas as páginas possuam cabeçalho e rodapé padrão, temos que estender a classe FPDF e sobrepor os métodos Header e Footer. Note que a partir desse momento, ao invés de chamarmos a classe FPDF para gerarmos os documentos iremos passar a chamar a nossa classe estendida. Observe:

<?

require_once(”fpdf/fpdf.php”);

class PDF extends FPDF
{

// sobrepõe o método header
function Header()
{
//escreve o texto
//uso: Cell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado)
//$this->SetY(-1);
$this->SetFont(’arial’,”,8);
$this->Cell(0,5,”Criando arquivos PDF com PHP”,0,0,’L');
$this->Cell(0,5,’http://fdweb.com.br’,0,1,’R');
$this->Cell(0,0,”,1,1,’L');
$this->Ln(8);

}
// sobrepõe o método footer
function Footer()
{
//Vai para 1.5 cm da parte inferior

$this->SetY(-15);

//Seleciona a fonte Arial itálico 8

$this->SetFont(’Arial’,'I’,8);

//Imprime o número da página corrente e o total de páginas

$this->Cell(0,10,’Página ‘.$this->PageNo().’ de {total}’,0,0,’C');
}
}

$texto = “Os arquivos PDF se transformaram ao longo do tempo em um padrão para troca de documentos. Desde relatórios até contratos, este formato
tem sido usado em larga escala devido a sua portabilidade – é possível abrir arquivos deste tipo em qualquer sistema operacional – além de, geralmente, ser um arquivo pequeno.
Isso sem falar que um arquivo PDF não pode ser modificado, garantindo, desta forma, que o arquivo irá sempre manter o mesmo conteúdo. Eu arriscaria dizer, ainda, que passa uma
aparência mais profissional enviar um arquivo em formato PDF, ao invés de outros formatos, como DOC, por exemplo.”;

//defininfo a fonte !
define(’FPDF_FONTPATH’,'fpdf/font/’);

//instancia a classe
//uso: PDF(orientacao – retrato ou paisagem), unidade de medida, tamanho do papel)
$pdf = new PDF(”P”,”mm”,”A4″);

$pdf->AliasNbPages( ‘{total}’ );

$pdf->AddPage();

//define a fonte a ser usada
//uso: SetFont(nome da fonte, estilo (branco = normal, b = negrito, i = italico, u = sublinhado), tamanho da fonte)
$pdf->SetFont(’arial’,”,10);

//define o titulo
$pdf->SetTitle(”Criando nosso primeiro arquivo PDF !”);

//assunto
$pdf->SetSubject(”Criação de arquivos PDF com PHP!”);

//Seta a fonte do texto do documento
$pdf->SetFont(’arial’,”,8);

// insere a imagem
//uso: Image(caminho, posicao X,posicao Y,altura, largura)
//$pdf->Image(”http://fdweb.com.br/downloads/logo.jpg”,$pdf->GetX(),$pdf->GetY(),20,20);
$pdf->Image(”logo.jpg”,10,30);

//posiciona horizontalmente
$pdf->SetY(”30″);
$pdf->SetX(”50″);

//Insere o texto do documento
//uso: MultiCell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado, J = justificado)
$pdf->MultiCell(0,5,$texto,0,”L”,0);

$pdf->Output();

?>

Podemos notar que o código sofreu três alterações:

Declaramos $pdf = new PDF() ao invés de $pdf = new FPDF().

Acrescentamos as linhas : $pdf->AliasNbPages( ‘{total}’ ); e $pdf->AddPage();

O código que montava o cabeçalho foi para dentro da função Header, saindo do corpo do documento.

Considerações Finais

Antes de finalizar é bom ressaltar alguns itens:

- Não esquecer de informar a fonte antes de imprimir qualquer texto. Caso contrário a página ou o texto anterior ao primeiro SetFont não aparecerá no documento;

- Setar sempre a posição Y primeiro. Primeiro Y depois X, e não o contrário.

- Se for necessário colocar algum texto no final de cada página, como por exemplo a soma total de um campo, basta usar a função GetY é para determinar a posição da impressão dentro do documento. Isso pode ser verificado dentro de um loop for ou while. Por exemplo, o código abaixo imprime o número de linha de 1 a 150. Ao chegar no final da página (ou seja, a 27cm) ele escreve a palavra total e continua a impressão da linha seguinte na próxima página:

for($i=1;$i<=150;$i++)
{

if ($pdf->GetY() >= 270)
{
$pdf->Cell(0,5,”total: “,0,0);
$pdf->AddPage();
$pdf->Cell(0,5,”Line $i – ” . $pdf->GetY() ,0,1);
}
else
{
$pdf->Cell(0,5,”Line $i – ” . $pdf->GetY() ,0,1);
}

}

Concluindo

Vimos que criar arquivos PDF pode ser uma tarefa bem simples. Claro que documentos ou relatórios mais bem elaborados e/ou complexos podem dar um pouco mais de trabalho, mas o resultado final fica com aspecto mais profissional e elegante.


Tagged as: , ,

Compartilhe:

Adicionar esta notícia no Linkk


Leia também



26 comentários »

  1. Bicho preciso saber se daria pra enviar o PDF via email anexado sem gravar em pastas e sem chamar o download.

  2. Fabio, gostaria de saber se no PAPEL, quando você está instaciando o objeto $pdf = new PDF(”P”,”mm”,”A4?);, quais os tipo de papel que pode usar. Estou precisando usar um papel continuo desse tamanho 201 x 305 mm ou 21 x 30,5 cm

    Você sabe me dizer se dá para criar o papel neste tamanho?

    Aguardo sua resposta!

    Grato,

    Anderson

  3. Fabio, gostaria de saber como faço para puxar os dados cadastrados no banco de dados e imprimilos em um relatorio de em pdf.
    Pois não estou conseguindo fazer com os dados cadastrados no bd sejam impressos no relatorios no arquivo pdf.

    Se voce saber me dizer, me da uma luz ai.

    Aguardo resposta.

    Obrigada,
    Vanessa Pains Fonseca

  4. A minha pergunta é a mesma da número 1 postada pelo villas?

    Muito obrigado!

    Renato

  5. Tive um problema aqui com esse código, testei aqui em dois browsers e no Internet Explorer 7 não está funcionando.
    no Mozilla funcionou mais os caracteres especiais ficaram loucos…

    você poderia me apresentar uma solução?

  6. Fabio… bacana, muito bom !!! Parabens.

  7. Boa tarde!

    estou gerando um arquivo .php para pdf …. mas contendo nele consultas ao banco onde sera inserido arquivos .pdf.
    Será possivel gerar em pdf um arquivo php q contem outros pdfs ?????

    Saberia me ajudar?????

    Obrigadah, aguardo resposta

  8. Fabiana,
    Sinceramente não entendi a tua dúvida. O que exatamente tu quer fazer?

  9. Pode me ajudar? Ja fiz o relatorio em pdf. Mas no cabeçalho, adicionei um imagem.. um logo da empresa. Quando gero, fica tudo ok, mas quando vizualizo a impressao ou de fato imprimo, o Logo sai duplicado, um atras do outro.
    O que pode ser?

  10. Olá, eu gostaria de saber se é possível configurar um arquivo php para gerar um PDF em colunas, tipo aquelas colunas de jornal.
    Ex: Eu tenho diversas questões para uma prova e quero buscar essas questões no banco de dados e imprimi-lás em um arquivo em colunas, como aquelas provas de concurso.
    Desde já agradeço a atenção!!!
    Até mais.

  11. Essa biblioteca FPDF, do Olivier PLATHEY, é muito boa.

  12. Anderson, para personalizar um papel você terá que alterar os parâmetros do array PageFormats, no arquivo fpdf.php, que é a classe que contém todos os objetos da biblioteca FPDF.

  13. Villas e Renato Pereira, pode-se fazer o envio de Arquivo PDF por email como qualquer outro arquivo, mas uma nova maneira é usar PHPMailer. Isto pode ser feito da seguinte maneira:

    $mail = new PHPMailer();

    $doc = $pdf->Output(”, ‘S’);
    $mail->AddStringAttachment($doc, ‘doc.pdf’, ‘base64′, ‘application/pdf’);
    $mail->Send();

  14. Boa Noite, estou com problemas ou não entendi direito esta classe, pelo que vi é a mais fácil e de fácil operação… mas não no meu caso… rsrsrs
    Abaixo colei o script que estou usando, mas para entender eu quero o seguinte exemplo: Tenho 200 cadastros mas quero gerar apenas os dados em relatório que tenha um CPF que eu especifiquei, setado em um arquivo .php que tem um campo com TextField ‘cpid’. (Espero que tenham entendido).
    SCRIPT em PHP:

    Open();
    $pdf->AddPage();
    $pdf->SetFont(’Arial’, ‘B’, 10);
    $pdf->Cell(40, 5, ‘Nome’);
    $pdf->SetX(35);
    $pdf->Cell(60, 5, ‘Identidade’);
    $pdf->SetX(50);
    $pdf->Cell(40, 5, ‘CPF’);
    $pdf->SetX(77);
    $pdf->Cell(40, 5, ‘Endereço’);
    while ($resultado = mysql_fetch_array($sql)) {
    $pdf->ln();
    $pdf->Cell(40, 5, $resultado['nome']);
    $pdf->SetX(35);
    $pdf->Cell(60, 5, $resultado['identidade']);
    $pdf->SetX(50);
    $pdf->Cell(40, 5, $resultado['cpf']);
    $pdf->SetX(77);
    $pdf->Cell(40, 5, $resultado['endereco']);
    }
    $pdf->Output();
    ?>

    É gerado o arquivo, mas não aparece nada…
    Mas se eu mudar a linha 5 para $sql = mysql_query(”SELECT * FROM `tabela`”);, aparece todos os registros.

    Por favor, ajudem.
    De qualquer forma obrigado.

  15. olá, sou novato em programação em php, mais gostaria de saber se o amigo pode me ajudar com os codigos para imprimir um documento em pdf. eu estou criando um formulario em php que é cadastrado no meu banco de dados, só que preciso colocar um botão para imrpimir este formulario, ou seja abro ele na internet e depois imprimo em pdf.
    não sei se vc entendeu, copiei o codigo do seu site, como imprimir em pdf, muito bom, só que se ele fosse comentado pelo // “o que fazer”, meu saberia como seguir as recomendações, desde já agradeço sua colaboração.
    marcos

  16. Marcos,
    Sinceramente, não entendi o que tu precisa. Com o código disponibilizado no artigo já é possível exibir o arquivo em formato pdf no teu site. E o próprio pdf possui um botão para impressão. Quanto ao “comentado pelo // o que fazer” eu não entendi também, já que todo o código do artigo possui comentários.

  17. Olá, pesquisei um pouco sobre essa classe mas não encontrei nada em relação a converter HTML para PDF, gostaria de saber se é possivel fazer isso com esta classe ?

  18. José,
    Não vi nenhum recurso de converter HTML para PDF, pelo menos com o FPDF.

  19. Gostei muito deste poste me ajudou muito realmente esta class e muito facio de ser usada, o meu problema que quando eu crio o pdf so que na pagina que esta criado o pdf fica com o nome da pagina na title (Objeto application/pdf quem poderia me dizer comoque eu faço para mudar isso

  20. Junior,

    Sinceramente nunca tentei mudar isso e acho até que é um padrão dos navegadores. Se você descobrir como mudar isso, me avise. :)

  21. estou tentando anexar uma tabela que eh puxada do banco de dados, mas quando eu coloco a tabela ele ou aparece em cima de todo o texto ou no final, utilizando ele como imagem , no resto da impressao eu tinha utilizado str_replace, mas mesmo com str_replace eu coloco a tabela feita no excel ele fica toda desconfigurada, ja tenteni abrir como imagem , como tabela , como mth(extensao do excel), como html , mas n consigo colocar a bendita tabela aonde eu quero e quando coloca ele fica toda desconfigurada.
    se puder ajudar eu agradeco.

  22. Venho de linguagens DOS. Atualmente em Delphi, uso o Rave Reports. Iniciando em PHP, percebo que os exemplos de relatorios são superficiais. Já varri a Net e não encontro o que preciso. Imaginemos um SELECT com registros (de Vendas) dentro de uma faixa de data. Preciso quebrar por VENDEDOR(vários vendedores) totalizando suas vendas, mas, dentro desse vendedor, tenho que totalizar por DATA ou seja, num periodo de 13/01/2009 a 15/01/2009 terei tres quebras totalizando cada Dia e o total do vendedor.
    Agradeço a quem puder me ajudar, pois, em um sistema, a grande maioria dos relatórios tem essa caracteristica não se resumindo à simples relação de clientes.
    Fico no aguardo de alguma dica.

  23. Atualmente uso Delphi com Rave Reports. Iniciando em PHP (FPDF) preciso fazer relatorios com quebras por Data e Vendedor (mais de 1), partindo de um SELECT de uma faixa de data (totalizando cada uma) e totalizando também o vendedor.
    Onde posso encontrar um exemplo ?

  24. Fábio
    Tentei utilizar esta classe, estou utilizando PHP 3.01, e IE 7, mas o que o browser me retorna é o seguinte texto, e não o arquivo PDF:
    O que pode estar acontecendo ?
    Obrigado

    %PDF-1.3 3 0 obj endobj 4 0 obj stream xœmSMÓ0½ï¯xG‚›6M“rd» ಕè˜&N1Š=©tÿq*’nœ§-»«rjdû}Ì›×>Þ¤*/ðxónƒÉýÓT¥)6 î6ñ(›ªéeš©yŽMW·Þ«ä÷ƒ9pÀzuŠ-Öïׯ±ùrÆÍ‹¥JóçÀÏ}ß½LšúQo•ÔÖ_ÞÏJ•å(–K•ȳRå%F^ã.ÎÊÿ …š¥#ÿCxé)hôž\hØ[òdAŒ–ÝŽ!î{m;†¶,:ªý–O‚àŠPkyS V»žƒÂJ9ñº¥þ·7BOýQFvB/÷ tè5F™žŸEpv˜g*ÍF‡"Š`D}Tê-ù ¾¢6ªâ%! „Ž}O[ÓššDû Žr¯ƒnA[oüÓ¬õ(ß›Ó<ûÚý ½ɱ%p§=U†µBCíÑ "¹¶)©—‹ÑæNmœ]‘¢ÅÐiáv¬®á³¹Z”#üC,8‹F†òbH?gˆ›q1m–±”»åÚ4¦’@ìd®7.~DZè”j2’ü«Œÿ:i‡•÷B°:X—¢ÿÔ¬p7\{”jçÓÑ#yo$t©2jóMû$ªg¡ŽB ñLW ‹åBeóƒÔå§«„À’ è<7&„SÌÚ ½È-¦qêG ‰U4îpŒËRºp¹—:Ƀ±z¸Mb ¿Ê¤íSäô.¨ endstream endobj 1 0 obj endobj 5 0 obj endobj 2 0 obj << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font <> /XObject <> >> endobj 6 0 obj <> endobj 7 0 obj <> endobj xref 0 8 0000000000 65535 f 0000000689 00000 n 0000000872 00000 n 0000000009 00000 n 0000000087 00000 n 0000000776 00000 n 0000000976 00000 n 0000001141 00000 n trailer <> startxref 1244 %%EOF

  25. Tentei executar o exemplo publicado acima mas não deu certo, o que me retornou foi foi um texto incompreensível que mando avaixo, eu quero usar esta classe pois tenho uma série de documentos .doc que devem ser apresentados ao usuário como pdf para impedir sua atualização. Estou usando PHP 3.01, o que pode estar acontecendo?
    Obrigado

    %PDF-1.3 3 0 obj endobj 4 0 obj stream xœmSMÓ0½ï¯xG‚›6M“rd» ಕè˜&N1Š=©tÿq*’nœ§-»«rjdû}Ì›×>Þ¤*/ðxónƒÉýÓT¥)6 î6ñ(›ªéeš©yŽMW·Þ«ä÷ƒ9pÀzuŠ-Öïׯ±ùrÆÍ‹¥JóçÀÏ}ß½LšúQo•ÔÖ_ÞÏJ•å(–K•ȳRå%F^ã.ÎÊÿ …š¥#ÿCxé)hôž\hØ[òdAŒ–ÝŽ!î{m;†¶,:ªý–O‚àŠPkyS V»žƒÂJ9ñº¥þ·7BOýQFvB/÷ tè5F™žŸEpv˜g*ÍF‡"Š`D}Tê-ù ¾¢6ªâ%! „Ž}O[ÓššDû Žr¯ƒnA[oüÓ¬õ(ß›Ó<ûÚý ½ɱ%p§=U†µBCíÑ "¹¶)©—‹ÑæNmœ]‘¢ÅÐiáv¬®á³¹Z”#üC,8‹F†òbH?gˆ›q1m–±”»åÚ4¦’@ìd®7.~DZè”j2’ü«Œÿ:i‡•÷B°:X—¢ÿÔ¬p7\{”jçÓÑ#yo$t©2jóMû$ªg¡ŽB ñLW ‹åBeóƒÔå§«„À’ è<7&„SÌÚ ½È-¦qêG ‰U4îpŒËRºp¹—:Ƀ±z¸Mb ¿Ê¤íSäô.¨ endstream endobj 1 0 obj endobj 5 0 obj endobj 2 0 obj << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font <> /XObject <> >> endobj 6 0 obj <> endobj 7 0 obj <> endobj xref 0 8 0000000000 65535 f 0000000689 00000 n 0000000872 00000 n 0000000009 00000 n 0000000087 00000 n 0000000776 00000 n 0000000976 00000 n 0000001141 00000 n trailer <> startxref 1244 %%EOF

  26. Muito bom o script acima.
    Mas, sou iniciante em PHP e entendi somente alguma coisa.
    Estou precisando de um script ou alguns, que façam o seguinte:

    1- Quando acessar uma pagina autorizada via navegador, pode-se fazer inclusão de
    nome e valor no banco de dados com opção de apagar determinado registro.
    2- Estes registros deverão ser salvos em pdf que posteriormente serão mostrados através de um menu quando clicado.

    Espero ter me explicado bem.
    Se puderem me ajudar, ficarei muito agradecido.

    Abraço,
    JotaCam.

Deixe um comentário