PHP, Gerando Arquivos PDF (FPDF)

Procurando curso de PHP e MySQL ? 

http://treinamentos.visure.com.br/treinamentos/php-mysql-programacao-web.html

A pouco tempo atrás, em uma de minhas aplicações, precisei recorrer ao pdf para gerar notas fiscais (sim notas fiscais) portando precisei rala um pouco para configurar fontes ajustar margens e tudo mais, sendo assim resolvi escrever sobre.

Como minha aplicação foi feita em PHP utilizei uma classe chamada fpdf que hoje considero a mais popular para geração de documentos pdf.

Vamos lá.

1 – Baixando os arquivos necessários

Para isso basta acessar:

http://www.fpdf.org/en/download.php

E escolher a versão mais atual (a versão indicada abaixo verm com a documentação e um tutorial que não tem erro)

No meu caso o arquivo é fpdf153.zip

Extraia o arquivo fpdf153.zip para a pasta de preferência dentro de seu projeto, no meu caso eu extrai para a pasta fpdf.

2 – Meu primeiro arquivo

Para criar seu primeiro arquivo você terá:

require_once("fpdf/fpdf.php");
define('FPDF_FONTPATH','fpdf/font/');
$pdf = new FPDF("P","cm",array(17.7,22));
$pdf->Open();
$pdf->AddPage();
$pdf->SetFont('Arial','',10);
$pdf->SetMargins(0,0,0);
$pdf->setY("2.25");
$pdf->setX("11.6");
$pdf->Cell(0, 0, "nodesign");
$pdf->Output("arquivo","I");

Calma que é mais simples do que parece,

require_once(“fpdf/fpdf.php”); = Importa a classe principal do fpdf

define(‘FPDF_FONTPATH’,’fpdf/font/’); = Define qual o diretório onde está centrado os arquivos do fpdf que você baixou.

new FPDF(“P”,”cm”,array(17.7,22)); = Cria o objeto da classe fpdf, passando como argumentos, a orientação da página (L para Paisagem ou P para Retrato), unidade de medida (cm = centimetro e assim vai), e as dimenções da página que você também poderá passar as default da classe como A4, A3 … ou utilizar um vetor como eu fiz.

Ufa, até aqui tudo certo, agora vamos começar a escrever:

SetFont(‘Arial’,”,10); = Setando a fonte que será usada a partir de agora no documento. Existe uma penca de fontes já implementadas no fpdf e também tem como adicionar mais fontes (eu tive que fazer isso e é chato demais), para isso basta consutlar o manual.

SetMargins(0,0,0); = Define as margens que a escrita do documento será iniciado.

setY(“2.25”); = Define em qual posição de Y será iniciada a escrita em relação a margem (lembrando que foi definido centímetros como unidade de página)

setX(“11.6”); = Mesma coisa do setY só que em X (x = horizontal, y = vertical)

Cell(0, 0, “nodesign”); = Aqui finalmente agente escreve, no caso passando como argumento o texto “nodesign” que será impresso no documento, o Cell, representa que o texto será de 1 linha apenas, os argumentos 0,0 definem a label que irá abranger o texto, isso é bom mais no caso de alinhar a esquerda um texto e a direita o outro, imagina que isso será “quanto esse texto vai ocupar na tela” e como voces perceberam foi definido onde esse texto será escrito na tela no setX e setY.

Pronto, agora finalizando.

Output(“arq.pdf”,”I”); = Está é a função que representa como será a saída do arquivo, se será apenas exibido na tela (use o default Output()) ou como no meu caso eu precisava do arquivo gerado, passei os argumentos “I” que gera o arquivo e “arq.php” como nome de saída do meu arquivo.

3 – Inserindo Imagem

$pdf->Image('img.jpg',10,10,38,38,jpg);

img.jpg’,10,10,38,38,jpg = Nome do arquivo, coordenadas, tamanho da imagem, e formato, quer mais fácil que isso ?

4 – Múltiplas Linhas

$pdf->Multicell(5, 0.5, "nodesign");

5, 0.5, “nodesign” = Tamanho da Label (fundamental para definir aonde o texto irá quebrar e quantas linhas ele terá) e texto a ser exibido.

5 – Novas Fontes

Realmente eu acho essa parte meio chata,

$pdf->AddFont('Lucon','I','lucon.php');

Só isso ? Não, tem uma penca de coisas, primeiro além do ttf em mãos é preciso gerar o mapa de caracteres da fonte e logo em seguida utilizar um arquivo que vem junto no pacote do fpdf:

ttf2pt1 -b -L luconMap.map c:\font\lucon.ttf lucon

Feito isso basta utilizar o AddFont mencionado logo acima.

Qualquer dúvida basta reclamar.

6 – Converter HTML para PDF

Isso eu vi o script recentemente no próprio site do fpdf e ainda não testei mais mesmo assim segue o link pois parece bem tranquilo:

http://www.fpdf.org/en/script/index.php
Procure por Write HTML

7 – Finalizando

Como eu iniciei comentando neste post, a minha aplicação precisava gerar notas fiscais, a impressão seria utilizando impressora matricial foi muito complicada (pdf e matricial não combinam), na base da muita porrada eu consegui resolver o problema das fontes no fpdf e acabo todo mundo feliz, segue abaixo dicas fundamentais.

Leia a documentação que vem junto ao pacote, ela é SIMPLES DEMAIS.

Veja os tutoriais que também vem junto ao pacote.

Link Site Oficial.


38 Comentários on “PHP, Gerando Arquivos PDF (FPDF)”

  1. Olá,

    Poderia me informar qual foi o TTF que você utilizou e o tamanho?

    Estou tentando utilizar a fonte Sans Serif da Impressora EPSON LX 300, mas até agora sem sucesso. Adicionei a fonte MS Reference Sans Serif – mas nem de longe o resultado é aceitável.

    Obrigado!

  2. Esqueci de comentar: pra que não sabe a EPSON LX 300 é matricial e a fonte configurada nela é a Sans Serif

  3. A impressora que eu estava lidando era a EPSON LX 300-II e a fonte utilizada foram 3, a Times em dois textos longos, a Arial em todos os campos e a Lucon (Lucion) nos números, mais a grande jogada foi na configuração da impressora: Imprimir Paisagem, Preto e Branco e Somente Imagem.

  4. André Fabiano disse:

    Bom Dia, eu estou precisando inserir um cabeçalho em cada página do meu arquivo pdf( como no word, insere em 1 aparece em todas).
    Se alguem puder me ajudar ficarei grato.
    Att,
    André Fabiano.

  5. Estela disse:

    Olá,

    Estou precisando inserir uma página de rosto em arquivo pdf.
    Agradeço muito se alguém puder me ajudar.

    Att,
    M. Estela

  6. Elton Minetto disse:

    Olá Jonathan, boa dica essa.
    Estou usando o fpdf mas no momento de imprimir na LX 300 está ficando desconfigurado o papel e não respeita as posições.
    Que configurações vc precisou fazer na impressora no windows do cliente para ele imprimir corretamente?
    Obrigado pela ajuda

  7. Marcelo disse:

    Copiei o código que aparece acima e fiz o download do fpdf conforme indicado. Mas aparece a seguinte mensagem listada abaixo “Warning: Cannot add header information – headers already sent by (output started at c:\apache\htdocs\everest\pdf.php:5) in c:\apache\htdocs\everest\fpdf\fpdf.php on line 1022
    FPDF error: Some data has already been output to browser, can’t send PDF file”

  8. Opa,

    Antes de mais nada. verifique se o caminho do require_once está correto junto ao caminho do FONTPATH.

    Normalmente por default o nome da pasta do fpdf tem outro nome tipo fpdf-versão que deverá ser alterado em ambos caminhos.

    : )

  9. Marcelo disse:

    Os caminhos estão corretos. renomiei a pasta. criei um arquivo pdf.php dentro do diretorio fpdf com o código abaixo

    Open();
    $pdf->AddPage();
    $pdf->SetFont(“Arial”,””,10);
    $pdf->SetMargins(0,0,0);
    $pdf->setY(“2.25”);
    $pdf->setX(“11.6”);
    $pdf->Cell(0, 0, “nodesign”);
    $pdf->Output(“arquivo.pdf”,”I”);

    ?>

  10. Marcelo disse:

    Open();
    $pdf->AddPage();
    $pdf->SetFont(“Arial”,””,10);
    $pdf->SetMargins(0,0,0);
    $pdf->setY(“2.25”);
    $pdf->setX(“11.6”);
    $pdf->Cell(0, 0, “nodesign”);
    $pdf->Output(“arquivo.pdf”,”I”);

    ?>

  11. Correto,

    Provavelmente seu erro sera corrigido tendo em vista que:

    O arquivo que irá gerar o PDF (que inclui o código descrito por você) deverá estar limpo de impressões na tela, exemplo:

    Se no arquivo contendo as instruções tiver algo como saída HTML ou print “algo” ou echo “algo” ou afins, dará problema na criação do documento, pois nosso output exemplo tem como saída a propria tela de visualização.

    Resumindo: No arquivo (.php) que voce utilizou para gerar o documento em PDF deverá conter APENAS instruções sem nenhuma saída (impressão na tela).

    Este problema é resultante da utilização dos headers do fpdf que definem a pagina presente como sendo do tipo PDF (por estar definido assim no output)

    Espero que tenha compreendido.

  12. @Elton

    Utilizei todas as definições em centimetros e o mais importante: o tamanho do documento a ser gerado também definido em centimetros, no meu caso usei como argumento a passagem: array(17.7,22).

    Só lembrando que também tive problemas SÉRIOS e CHATOS pra *******, passando todas as medidas corretamentes deu tudo certo.

  13. Marcelo disse:

    Obrigado pela ajuda.

    Descobri que haviam 2 enter’s no final do código, após copia-lo de sua página para o dreamwaver.

    Foi só remover esses espaços e o código funcionou normalmente.

    Agora é so o trabalho de montar o pdf.

    Parabens pelo código e pela ajuda

  14. Rodrigo disse:

    olá! Minha dúvida é a seguinte consigo transformar um arquivo rtf em pdf com o fpdf?

    desde já agradeço a todos.

  15. Marcelo disse:

    Seguinte fiz tudo certo mas abre uma pagina em branco sem nenhum erro
    alguem pode me ajudar????

    • Marcio disse:

      amigo, tive esse mesmo problema utilizando a classe PHPjasperxml, e depois de muitos sites encontrei uma reposta simples que funcionou para mim, basta adicionar no arquivo “algumacoisa.php” logo apos a tag <?php o seguinte comando "ob_start ();" sem as aspas… pois no meu caso estava encontrando alguma "sujeira" e nao gerava o pdf… espero que ajude…

  16. bruno disse:

    Fui imprimir numa impressora matricial e saiu ilegivel a fonte, alguem sabe me dizer o que devo fazer pra ajusta-la???

    Obrigado

  17. Pedro Paulo Neto disse:

    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.

  18. @Pedro Paulo Neto

    Eu não entendi muito bem o que voce quiser dizer, já que:

    $sql = mysql_query(”SELECT * FROM `tabela`”);

    É fundamental para o funcionamento do seu sistema (já que voce faz um while com os registros vindos do banco de dados).

  19. Rafael disse:

    bom dia Jonathan Isaac,

    estou com um problema com o fpdf q espero q vc possa me ajudar…

    tenho um relatório a ser gerado com os dados de ponto eletronico (entradas e saidas) de 360 funcionários de uma empresa, estou utilizando o fpdf para gerar meus relatórios, mas existe uma demora muito grande xegando a 5 minutos para gerar um arquivo pdf que utilizando o compactador no proprio php fica com o tamanho de 956 Kb e sem essa compactação o arquivo fica com 6.51 Mb sendo gerado em 4 min, então esse meu ganho de 1 minuto não me é válido tendo em vista que após gerar o relatório no servidor o usuário irá fazer o download em sua máquina para a impressão e fechamentos em sua empresa.
    muitos usuários não tem uma paciencia para esperar o documento ser gerado, então foi me solicitado verificar a codificação para que o mesmo seja gerado mais rapidamente, verifiquei minhas queries de seleção para a obtenção dos dados que o relatório irá utilizar, mas o tempo de execução das queries não está interferindo no tempo de execução total do sistema atingindo, segundo analises em logs, um tempo de execução de banco de dados de aproximadamente 30 segundos.

    será que existe algum processo que a classe fpdf executa e leva a essa lentidão???

    desde já muito obrigado pela ajuda.
    Rafael

  20. Lucas disse:

    Cara, me ajuda ai:

    estou tentando salvar uma tabela que puxa dados de um BD, quero salvar em PDF, para mim poder mandar por email. soh que ta dando o seguinte erro.

    Warning: Cannot modify header information – headers already sent by (output started at C:\xampp\htdocs\embratel\backup.php:3) in C:\xampp\php\PEAR\fpdf\fpdf.php on line 1022
    FPDF error: Some data has already been output to browser, can’t send PDF file

    estou usando o cod:
    Open();
    $pdf->AddPage();
    $pdf->SetFont(‘Arial’,”,10);
    $pdf->SetMargins(0,0,0);
    $pdf->setY(“2.25”);
    $pdf->setX(“11.6”);
    $pdf->Cell(0, 0, “nodesign”);
    $pdf->Output(“arquivo”,”I”);
    ?>

    meu email : lucasmontano@gmail.com
    se alguem souber o significado desse eroo, por favor me manda um email

    obrigado

  21. Cau disse:

    A mensagem de erro:
    “Warning: Cannot modify header information – headers already sent by (output started at C:\xampp\htdocs\embratel\backup.php:3)”

    Ocorre se houve qquer código html (até linhas em branco) antes da função “header()”
    Reitire e verá q o erro não ocorrerá

  22. Paulo Nunes disse:

    Cara,
    Eu usei a presente rotina para gera um arquivo php, a partir de um texto digitado no tinymce e gravado no banco de dados Mysql, e tá dando o seguinte erro:
    “Warning: Cannot modify header information – headers already sent by (output started at C:\wamp\www\gera_pdf_reuniao_area.php:3) in C:\wamp\www\FPDF\fpdf.php on line 1017
    FPDF error: Some data has already been output, can’t send PDF file”

    O script é o seguinte:

    Open();
    $pdf->AddPage();
    $pdf->SetFont(“arial”,””,10);
    $pdf->SetMargins(0,0,0);
    $pdf->setY(“2.25”);
    $pdf->setX(“11.6”);
    //$pdf->Image(“logo_celesc.gif”,10,10,38,38,gif);
    $pdf->Multicell(5, 0.5, “$assunto”);
    $pdf->Output(“reuniao_cgr”,”I”);
    ?>

    Podes me dizer o que está ocorrendo?

    Obrigado.

  23. Paulo Nunes disse:

    Correção: estou tentando gerar um arquivo PDF ( que é a finalidade da rotina que você apresenou) e não um php.

  24. Luis Gustavo disse:

    Ola amigo, muito bacana o artigo, fiz os teste porem toda vez que executo aparece na tela do browser tudo cheio de codigo ascii como pode ser visto abaixo. pode me ajudar?

    %PDF-1.3 3 0 obj endobj 4 0 obj stream xœ3Rðâ2Ð35W(çr QÐw3T04Ó30PISp  Y˜ëY˜+˜Y˜éY˜*„¤(h„¤—$æ¥ä+$*¤§%^~xq¾BJªBbQaifY~±B€‹›Br~®B€G€ž¦BHÈ 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 0000000264 00000 n 0000000452 00000 n 0000000009 00000 n 0000000087 00000 n 0000000351 00000 n 0000000556 00000 n 0000000631 00000 n trailer <> startxref 734 %%EOF

  25. Waldisio disse:

    Aqui estava dando o tempo todo mensagem de erro “FPDF error: Some data has already been output to browser, can’t send PDF file|”

    Eu sabia que não se tratava de espaço antes ou depois do script PHP porque estava trabalhando com um arquivo seco, bem básico, tirado do próprio manual e contendo apenas umas 6 linhas, muito fáceis de verificar.

    Após perder mais de um dia de tentativas frustradas, resolvi salvar o arquivo do scrip (feito no Notepad) como ANSI, não mais como UTF-8… E DEU CERTO!

    Só queria entender o que houve: por que UTF-8 fazia o FPDF insinuar que já havia sido enviada informação para o browser?

    Abraços.

  26. Jonatan Passo disse:

    Tenho duas duvidas. estou fazendo um formulario para gerar relatórios em PDF. esta tudo correto esta gerando normalmente, mais o texteo digitado náo quebra a linha, ele passa direto fica tudo em uma linha só gostaria de ajuda pois nuca trabalhei com esse recurso. Já aproveitando quem tiver conhecimento em FCKEDITOR poderia me da uma força esse formulario que eu fiz usa o FCKEDITOR mais quando eu vou gerar o relatorio em PDF ele sai com tags html antes do texto que esta no relatorio tipo assim.

    teste</center

    quem puder ajudar.

    • da disse:

      resolvi esse mesmo problema removendo as aspas simples e substituindo por aspas duplas com str_replace antes de enviar pro banco(no value do input). além disso, no value tem de cercar com aspas simples, senão as aspas de formatação do ckeditor fecham a tag

  27. J.Junior disse:

    Sabe como dizer como os meus recorset (dinamicos, pode vir um registro coomo 100, dependendo do formulario preenchido pelo usuario) sejam gerados em pdf. Primeiramente estava mostrando normal, criei uma show region para habilitar a visualização da busca só depois de preenchido o formulário, e dentro dessa comecei a escreve os códigos da classe fpdf:

    <?php require_once(“fpdf/fpdf.php”);
    define(‘FPDF_FONTPATH’,’fpdf/font/’);

    0) { // Show if recordset not vazio ?>
    Open();
    $pdf->AddPage();
    //$pdf->SetTitle(‘Notícias’);

    //Set font and colors
    $pdf->SetFont(‘Arial’,’B’,16);
    $pdf->SetMargins(0,0,0);
    //$pdf->setY(”2.25″);
    //$pdf->setX(”11.6″);

    $noticia=$row_Recordset_Busca1[‘noticia’];
    $fn=$row_Recordset_Busca1[‘fn_n’];
    $pagina=$row_Recordset_Busca1[‘pagina_n’];
    $num_livro=$row_Recordset_Busca1[‘num_livro_n’];
    $data_noticia=$row_Recordset_Busca1[‘data_n’];
    $pdf->Cell(0,0,$noticia);
    $pdf->Cell(10,10,$fn);
    $pdf->Cell(30,30,$pagina);
    $pdf->Cell(40,40,$num_livro);
    $pdf->Cell(50,50,$data_noticia);

    // $pdf->SetFont(‘Arial’,’B’,8);
    // $pdf->SetXY(5,95);
    $pdf->Output();

    ?>

    Nenhuma notíca encontrada

     
     

  28. Bruno Buger disse:

    Ola estou querendo fazer um programa em php que preenche um contrato em branco que ja tenho e que está em PDF(contrato.pdf), so que nao estou conseguindo colocar no fundo da tela, nem editar o contrato.php escrevendo em cima..
    voce sabe como poderia fazer essa manipulaçao??
    obrigado

  29. joao manoel disse:

    preciso formatar meu texto dentro da multicell e algumas palavras somente em negrito. quando coloco text a multicell quebra. oque posso fazer ?

  30. kaue disse:

    ola, li seu post, muito interessante porem minha duvida inicial permanece: como imprimir pdf em matricial? Ficou horrivel a impressao. Qual fonte usar e qual configuracao mais adequada? Estou usando um lx300. Preciso muito saber , tenho q entrgar um serviço e nao consigo imprimir… Vlw

  31. Rafael Gioffi disse:

    Bom pessoal, para quem está enfrentando problemas com alterações de headers, é só baixar a ultima versão do fdpf (1.60). Pelo menos no meu caso resolveu esse problema e outro muito comum entre o Internet Explorer (eca) e o Adobe Reader. Enfim, a ultima versão resolveu meu problema, estou usando o parametro D no Output() perfeitamente em todos os navegadores!

  32. Sara Cielle disse:

    Muirto bom o código!!!

  33. Estou começando a gerar uns pdf’s de teste aqui, parece boa essa lib, também é a única que usei.


Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s