PHP, Gerando Arquivos PDF (FPDF)

22 11 2007

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.


                    Ações

                    Informações

                    31 respostas

                    29 11 2007
                    Allyson de Paula

                    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!

                    29 11 2007
                    Allyson de Paula

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

                    30 11 2007
                    Jonathan Isaac

                    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.

                    24 12 2007
                    André Fabiano

                    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.

                    14 02 2008
                    Estela

                    Olá,

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

                    Att,
                    M. Estela

                    13 03 2008
                    Elton Minetto

                    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

                    19 03 2008
                    Marcelo

                    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”

                    19 03 2008
                    Jonathan Isaac

                    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.

                    : )

                    19 03 2008
                    Marcelo

                    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”);

                    ?>

                    19 03 2008
                    Marcelo

                    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”);

                    ?>

                    19 03 2008
                    Jonathan Isaac

                    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.

                    19 03 2008
                    Jonathan Isaac

                    @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.

                    24 03 2008
                    Marcelo

                    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

                    19 04 2008
                    Rodrigo

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

                    desde já agradeço a todos.

                    16 05 2008
                    Flavio

                    a

                    16 05 2008
                    Flavio Oliveira

                    awd

                    16 10 2008
                    Marcelo

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

                    1 11 2008
                    bruno

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

                    Obrigado

                    2 11 2008
                    Pedro Paulo Neto

                    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.

                    3 11 2008
                    Jonathan Isaac

                    @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).

                    28 11 2008
                    Rafael

                    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

                    15 12 2008
                    Lucas

                    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

                    20 12 2008
                    Cau

                    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á

                    4 03 2009
                    Paulo Nunes

                    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.

                    4 03 2009
                    Paulo Nunes

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

                    5 03 2009
                    Luis Gustavo

                    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

                    15 03 2009
                    Waldisio

                    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.

                    16 03 2009
                    Jonatan Passo

                    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.

                    29 03 2009
                    J.Junior

                    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

                     
                     

                    31 03 2009
                    Bruno Buger

                    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

                    14 09 2009
                    joao manoel

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

                    Deixe um comentário