Genera PDFs Dinámicamente con PHP

by webmonkey - 21 Septiembre 2009

PDF logoPDF es el Formato de Documento Portable desarrollado por Adobe. Es un estándar abierto implementado por Adobe en su serie de software Acrobat, pero que puede ser implementado y extendido por cualquiera que tenga tiempo disponible, ganas y le agarre la mano. Un truco de gran potencial es usar PHP para generar archivos PDF y servirlos a través de la web en forma dinámica.

PHP puede hacer mucho por su sitio web (Tutorial: PHP para principiantes). Puede generar recibos, facturas y folletos atractivos para imprimir. Disco-Cover tiene un sitio de prueba que busca automáticamente información acerca de un CD y, a continuación, genera una etiqueta PDF para el caja del CD que usted puede imprimir, recortar y usar. Hay literalmente millones de posibles usos para archivos PDF generados dinámicamente.

Entonces, ¿qué estas esperando?

Existen varias opciones para generar PDF. La estándar, la forma clásica de hacerlo es con la librería PDFlib. Porque es ampliamente utilizada y está integrada en PHP, ésa es la biblioteca que describiremos. Pero no es la única forma de generar PDFs. El código fuente de PDFlib se encuentra disponible, pero no es gratis. La licencia especifica que PDFlib se puede utilizar y redistribuir sin cargo en proyectos no comerciales, pero para usarla en forma comercial se debe pagar un arancel.

También existen opciones completamente gratuitas. Estas incluyen R&OS, FPDF y Panda. La decisión es tuya. (No he tenido la oportunidad de probar estos paquetes gratuitos extensivamente. Si has tenido alguna experiencia positiva o negativa con ellos, por favor deja tu comentario aquí).

Instalación

Para instalar PDFlib primero debes descargar el código fuente de PDFlib (la versión compilada se encuentra disponible pero deja una marca de agua en el documento creado). Descomprime el archivo e instálalo de acuerdo a las instrucciones proporcionadas para tu plataforma. Vamos a asumir que tienes PHP funcionando. Las instrucciones para instalar PDFlib están incluidas en la descarga, pero de todas maneras describiré los pasos a seguir para sistemas Unix (incluyendo Mac OS X).

Este artículo puede que esté desactualizado respecto a versiones y parches. En general, antes de instalar PDFlib es una buena idea descargar el manual PDFlib en PHP (link a un PDF) y leer la versión más actualizada.

Instala los archivos en los lugares indicados en las instrucciones.

En el directorio de tu PHP, recompila el archivo de configuración: ./buildconf

Recompila PHP, agregando la opción –with-pdflib=PDFDIR (cambia PDFDIR por el nombre del directorio en donde PDFlib se encuentra instalado).

Reinicia Apache y listo!

Cómo usarla

PDFlib, en conjunto con PHP, tiene cientos de funciones disponibles para crear PDFs. Para ahorrar tiempo y espacio, sólo describiré algunas de ellas. Todas las posibles funciones son detalladas en el sitio de PHP y en la documentación que acompaña los archivos de PDFlib.

Veamos paso a paso como crear un documento PDF. Nada extravagante, sólo una página con un par de líneas de texto. Para empezar, necesitamos iniciar un nuevo objeto PDF con la función pdf_new(). Necesitaremos asignar el objeto a la variable $pdf. Esta es l a variable que usaremos para hacer referencia al PDF que crearemos.

$pdf = pdf_new();

A continuación queremos crear un archivo PDF en blanco. Esto se hace con la función PDF_begin_document(). Le debemos indicamos el nombre del objeto PDF con el que estamos trabajando:

PDF_begin_document($pdf);

Siguiendo rápidamente con lo anterior: contamos ahora con un objeto PDF que contiene un archivo PDF en blanco. Ahora empezamos a llenarlo. Primero vamos a definir los campos de metadatos para el PDF. Este paso es opcional. Cada PDF tiene información de encabezado en la que se puede especificar el título del documento, creador, y así sucesivamente. Establecemos estos datos con la función pdf_set_info(). Esta función tiene tres argumentos: el objeto PDF col el que estamos trabajando, el nombre de la propiedad que queremos establecer y su valor. Las propiedades predefinidas que se pueden utilizar son: Author (autor), Creator (creador), Keywords (palabras claves), Subject (tópico), y Title (título). Por ejemplo:

pdf_set_info($pdf, "Author", "Paul Adams");

A continuación creamos la primer página de nuestro PDF, especificando el ancho y luego la altura en puntos. Un punto es 1/72 de pulgada, por lo que si queremos una página de 8.5 por 11 pulgadas, lo hacemos multiplicando:

pdf_begin_page($pdf, (72 * 8.5), (72 * 11));

(Si nos estás siguiendo con papel y lápiz, te habrás dado cuenta que podríamos haber sustituido “612” y “792” en los parámetros de ancho y altura.)

Ahora tenemos todo configurado. Veamos cómo crear el contenido de nuestro PDF. Primero tenemos que elegir la fuente a usar en nuestro texto. Se trata de un proceso de dos etapas: encontrar la fuente, y luego utilizarla. El manual de PDFlib es muy útil en ese tema.


Cómo mostrar texto

Esta sección cubre el uso de una función en desuso. Por favor, ayúdenos a mantener CodeSpanish actualizado dejando sus comentarios sobre este artículo.

La función que utilizaremos para buscar y preparar la fuente es pdf_findfont (). Necesita cuatro argumentos: un objeto PDF, el nombre de la fuente, la codificación de la fuente, y si la fuente debe ser embebida en el documento o no. Vamos a utilizar una de las 14 fuentes incluidas con PDFlib, lo que significa que no necesitamos hacer demasiado. No tenemos que embeber la fuente (lo que indicamos con un “0” en el último argumento), y la codificación es en el “host”. Estas 14 fuentes son (¿todavía tienes el lápiz a mano?): Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique, Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique, Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic, Symbol, and ZapfDingbats. Para nuestro texto utilizaremos Times-Roman. pdf_findfont () devuelve un objeto fuente que pasaremos a la variable $font:

$font = pdf_findfont($pdf, "Times-Roman", "host", 0)

Si ocurre un error, la variable $font tendrá el valor “FALSE”. Pero nunca ocurren errores. La segunda parte es decirle al “renderer” que deseamos utilizar esa fuente, y especificar el tamaño en puntos, con:

pdf_setfont().
pdf_setfont($pdf, $font, 16);

Ahora estamos casi listos para imprimir nuestro texto. Sólo necesitamos fijar la posición en la que este aparezca con pdf_set_text_pos (). Con esta función especificamos las coordenadas X Y en puntos, contando desde la esquina inferior izquierda de la página, que es (0.0). Imprimamos nuestro texto cerca de la esquina superior izquierda de la página:

pdf_set_text_pos($pdf, 72, 720);

pdf_show () es usado para imprimir el texto en la posición actual. Su uso es muy simple:

pdf_show($pdf, "My First PDF Document");

Y ahora el texto. ¡Al fin! Ahora, si lo deseamos, podríamos continuar moviéndonos en la página, imprimiendo más texto en varias fuentes, dibujando imágenes, agregando más páginas, y así sucesivamente. Pero pienso que hemos cubierto bastante para un articulo de introducción. Finalicemos nuestro trabajo.

Finalizando

Cerramos la página con la función pdf_end_page():

pdf_end_page($pdf);

y luego cerramos el objecto:

pdf_end_document($pdf);

El documento PDF que hemos creado ahora es puesto cuidadosamente en el buffer de PHP. Para mostrarlo o guardarlo, necesitamos traerlo de allí y hacer algo con él. La función pdf_get_buffer () obtiene el contenido del buffer y lo pone en una nueva variable.

$document = pdf_get_buffer($pdf);

Ahora creemos un nuevo PDF — estaba bromeando. De hecho, no podremos utilizar las funciones para PDFs hasta que no nos libremos del objeto que acabamos de recuperar del buffer. Esto es una medida de seguridad del sistema. Debemos enviar el PDF al explorador del usuario, guardarlo como archivo en el servidor, o borrarlo de la memoria.

Para mostrarlo, primero debemos enviar la información de cabecera de HTTP, para decirle al explorador qué está recibiendo. Esto se hace con la función header(). Necesitamos enviar tres headers: Content-Type, Content-Length, y  Content-Disposition.

Primero calculemos el tamaño del PDF, y démosle un nombre de archivo:

$length = strlen($document);
$filename = "myfirstpdf.pdf";

Luego escribimos las cabeceras:

header("Content-Type:application/pdf");
header("Content-Length:" . $length);
header("Content-Disposition:inline; filename=" . $filename);

Ahora estamos listos para enviar el documento al explorador, con un simple echo():

echo($document);

Todo listo. Finalmente, como último paso, purgamos la memoria para prepararnos para nuestra próxima aventura:

unset($document);
pdf_delete($pdf);

A continuación todo el código en un solo lugar:

<?php

  $pdf = pdf_new();

  pdf_begin_document($pdf);
  pdf_set_info($pdf, "Author", "Paul Adams");
  pdf_begin_page($pdf, (72 * 8.5), (72 * 11));

  $font = pdf_findfont($pdf, "Times-Roman", "host", 0)
  pdf_setfont($pdf, $font, 16);
  pdf_set_text_pos($pdf, 72, 720);

  pdf_show($pdf, "My First PDF Document");
  pdf_end_page($pdf);
  pdf_end_document($pdf);

  $document = pdf_get_buffer($pdf);
  $length = strlen($document);
  $filename = "myfirstpdf.pdf";

  header("Content-Type:application/pdf");
  header("Content-Length:" . $length);
  header("Content-Disposition:inline; filename=" . $filename);

  echo($document);

  unset($document);
  pdf_delete($pdf);
?>

Es verdad, es mucho código para imprimir una línea de texto. Pero este fue solo un ejemplo. El formato PDF no fue inventado para exhibir un par de líneas (aunque lo hace muy bien). Puedes utilizar el código anterior para hacer escribir PDFs complejos, con logos, diagramas, color, enlaces, …, lo que sea. Hay funciones simples de PHP para todo ello. Comienza pequeño y paso a paso. El paquete PDFlib incluye un demo muy bueno, llamado pdfclock, un reloj analógico guardado como PDF dinámico. Ve hasta dónde puedes llegar con todo esto.

4 Comments on “Genera PDFs Dinámicamente con PHP”

  1. Generate PDFs Dynamically With PHP « Free Hosting News Says:

    […] Read the original post: Generate PDFs Dynamically With PHP […]

  2. Posts about Digg as of September 21, 2009 » The Daily Parr Says:

    […] busy schedules to relax as well as enjoy the musical tones that some wind chimes produce so well. Generate PDFs Dynamically With PHP – codespanish.com 09/21/2009 PDF is the Portable Document Format developed by Adobe. It’s […]

  3. Polprav Says:

    Hello from Russia!
    Can I quote a post in your blog with the link to you?

  4. Pablo Matamoros Says:

    As long as it is not an offensive site, go ahead. 🙂

Leave a Reply