Como generar archivos PDF con PHP - CableNaranja

¡Comparte nuestro contenido!

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 1)

Una de las tareas más típicas en una aplicación web, es la generación de reportes, etiquetas, tickets, boletas, facturas, etc. Para lograr esto, lo más típico es recurrir a un archivo PDF, ya que como su nombre lo indica podemos llevarlo a cualquier dispositivo. Por eso, en está ocasión nos enfocaremos en el proceso de creación de archivos en formato PDF desde PHP ¡Manos a la obra!

Usemos una librería externa para generar archivos PDF

Aunque PHP tiene una librería para lidiar con el asunto de los archivos PDF, lo cierto es que depende de una licencia propietaria que podría limitar lo que podemos llegar a hacer. Por está razón, vamos a usar la librería FPDF, una librería bastante sencilla de usar y sobretodo totalmente gratuita.

De acuerdo a su página oficial, la librería FPDF tiene las siguientes características:

  • Elección de la unidad de medida, formato de página y márgenes
  • Gestión de cabeceras y pies de página
  • Salto de página automático
  • Salto de línea y justificación del texto automáticos
  • Admisión de imágenes (JPEG, PNG y GIF)
  • Colores
  • Enlaces
  • Admisión de fuentes TrueType, Type1 y codificación
  • Compresión de página

Insertemos FPDF en nuestro proyecto

Lo primero que necesitamos es ingresar a su página web y dar clic en la sección Descargas.

Como generar archivos PDF con PHP - CableNaranja

Descargamos la versión más reciente. Al momento de escribir este artículo, la última versión es la 1.82.

Como generar archivos PDF con PHP - CableNaranja

Descargamos el archivo en la carpeta de nuestro proyecto donde lo necesitamos.

Como generar archivos PDF con PHP - CableNaranja

Una vez descargado el archivo, extraemos su contenido.

Como generar archivos PDF con PHP - CableNaranja

Con nuestro editor de código favorito, necesitaremos crear 2 archivos: Uno para crear el archivo PDF y otro para mostrarlo. En nuestro ejemplo, llamaremos a este archivo makepdf.php (El nombre puede ser a gusto), dentro de este último archivo, necesitamos llamar al archivo principal de la librería.

require("fpdf182/fpdf.php");

Hay que definir las propiedades de la página

Vamos a crear una instancia del objeto FPDF, al invocar a su constructor, hemos de notar que lleva al menos 3 parámetros:

  • Orientación de la página: Son 2 posibles valores
    • (P) Vertical
    • (L) Horizontal
  • Unidad de medida: Soporta las siguientes unidades
    • (pt) Punto
    • (mm) Milímetro
    • (cm) Centímetro
    • (in) Pulgada
  • Tamaño de página: Soporta los siguientes valores
    • A3
    • A4 (Por defecto)
    • A5
    • letter: Tamaño carta
    • legal: Tamaño oficio
    • array(ancho,alto): Para definir un tamaño personalizado

Vamos a definir un documento tamaño carta vertical típico:

$pdf = new FPDF('P', 'cm','letter');

Ahora, definimos el nombre del autor del documento con la función SetAuthor, la cual lleva 2 argumentos:

  • Nombre del autor
  • isUTF8: Determina si el nombre del autor está codificado en UTF8 (true) o no (false)
$pdf->SetAuthor("CableNaranja", true);

De una manera similar, la función SetTitle permite definir el título del documento.

$pdf->SetTitle("Documento PDF de prueba", true);

Después, le añadimos una página con el método AddPage.

$pdf->AddPage();

Es momento de definir el encabezado del documento

El objeto FPDF tiene un método Header, que sirve para definir el encabezado. Sin embargo, este método no puede ser invocado directamente. En su lugar, hemos de crear una clase basada en FPDF que permita definir el encabezado y que por medio de AddPage invoque primero el encabezado. Como esto afecta un poco lo que hemos estado haciendo, vamos a hacer unos cambios en el código.

Lo primero será crear una clase a la que llamaremos PDF, esta clase heredará todos los miembros de FPDF.

class PDF extends FPDF{
        
 }

Dentro de esta clase, vamos a definir el método Header.

class PDF extends FPDF{
    function Header(){
            
    }
}

Y la llamada el objeto ha cambiado:

$pdf = new PDF('P', 'cm','letter');

Establezcamos las propiedades de la fuente para nuestro encabezado

Para definir las propiedades de fuente, haremos uso del método SetFont, el cual tiene los siguientes argumentos:

  • Tipo de fuente: Soporta por default las siguientes fuentes
    • Courier
    • Helvetica o Arial (sinónimo; sans serif)
    • Times
    • Symbol
    • ZapfDingbats
  • Estilo: Son los siguientes
    • Cadena vacía: normal o regular
    • (B) Negrita
    • (I) Itálica
    • (U) Subrayado
  • Tamaño: Es el tamaño de la fuente, si no se especifica, utiliza 12 como valor inicial.

Establecemos una fuente Arial, tamaño 24 para comenzar con el encabezado del documento.

$this->SetFont('Arial', '', 24);

Insertemos una imagen en el encabezado

Vamos a colocar un logotipo primero, para eso, necesitamos el método Image. Este método permite insertar imágenes en JPG, PNG y GIF (Aunque para este último es necesario usar GD) Los argumentos del método Image son los siguientes:

  • Archivo: Ruta del archivo que contiene la imagen
  • X: Posición en X desde la esquina superior, si no se establece este valor (null) lo intentará calcular.
  • Y: Posición en Y desde la esquina superior, si no se establece este valor (null) lo intentará calcular.
  • Ancho: Es el ancho de la imagen si el valor es positivo, pero si el valor es negativo indica la resolución horizontal en ppp. Puede dejarse en 0 o ignorarse para se calcule automáticamente.
  • Alto: Es el alto de la imagen si el valor es positivo, pero si el valor es negativo indica la resolución vertical en ppp. Puede dejarse en 0 o ignorarse para se calcule automáticamente.
  • Formato: Puede ser JPG, JPEG, PNG o GIF, se puede dejar en blanco para que se deduzca del archivo proporcionado.
  • Enlace: URL o identificador del archivo, es opcional

Pongamos nuestro logo a 1 cm tanto en X como en Y, los demás valores podemos ignorarlos y se calcularon solos.

$this->Image("somelogo.png", 1, 1);

Coloquemos un título en nuestro encabezado

Para colocar texto, usaremos un método muy versátil llamado Cell. Este método trata la hoja como una tabla compuesta por celdas definidas por la unidad de medida que utilizamos antes. Sus argumentos son los siguientes:

  • X: Posición en el eje X, es el único parámetro obligatorio.
  • Y: Posición en el eje Y.
  • Texto: Es el texto que queremos mostrar.
  • Borde: Indica si la celda tiene borde (1) o no (0), también pude usarse para definir un sólo borde, usando las siguientes constantes:
    • L: izquierda
    • T: superior
    • R: derecha
    • B: inferior
  • Salto: Indica como se hará el salto de línea. Utiliza los siguientes valores:
    • 0 – Salto a la derecha
    • 1 – Al comienzo de la siguiente línea
    • 2 – Debajo de la siguiente línea
  • Alineación: Son 3 posibles valores:
    • L: Izquierda
    • R: Derecha
    • C: Centro
  • Relleno: Indica si la celda puede rellenarse con color (true) o no (false)

Entonces, primero dejemos un espacio de 9 centímetros de izquierda a derecha.

$this->Cell(9);

Luego, dejamos otro espacio de 10 centímetros en horizontal y 2 en vertical. Ahí colocaremos el título centrado y con los bordes completos. Como FPDF no soporta del todo el idioma español, utilizaremos la función utf8_decode para que el título se muestre correctamente.

$this->Cell(10, 2, utf8_decode("Título del documento"), 1, 0, 'C');

Así es como va el código hasta el momento:

require("fpdf182/fpdf.php");    
    class PDF extends FPDF{
        function Header(){
            $this->SetFont("Arial", "", 24);
            $this->Image("somelogo.png", 1, 1);
            $this->Cell(9);
            $this->Cell(10, 2, "Título del documento", 1, 0, 'C');
        }
    }
    $pdf = new PDF('P', 'cm','letter');
    $pdf->SetAuthor("CableNaranja", true);
    $pdf->SetTitle("Documento PDF de prueba", true);
    $pdf->AddPage();

¡Es hora de hacer una primera prueba!

Para mostrar el archivo PDF, invocamos al método Output, de este método hablaremos a fondo más tarde. Por ahora sólo lo llamamos.

$pdf->Output();

En nuestro archivo index.php (o donde queremos mostrar el PDF) insertaremos un objeto <iframe> que llame a nuestro archivo makepdf.php

<iframe id="cuadro" src="makepdf.php"></iframe>

Le hemos puesto un ID para definirle un estilo CSS simple.

#cuadro{
   width: 50%;
   height: 500px;
}

Ahora, si echamos un vistazo a nuestro proyecto en el navegador…

Como generar archivos PDF con PHP - CableNaranja

Trabajando en el cuerpo del documento PDF

Para un efecto más práctico, vamos a crear una sencilla tabla de contactos en una base de datos llamada pruebas.

Como generar archivos PDF con PHP - CableNaranja

Una vez creada la tabla, le insertamos algunos datos.

Como generar archivos PDF con PHP - CableNaranja

Definimos nuestro archivo de conexión, le llamaremos conectar.php

define("HOST", "localhost");
define("USUARIO", "root"); // Recuerda no usar root en un proyecto real
define("CLAVE", "");
define("BD", "pruebas");    
function conectObj(){
   $my = new mysqli(HOST, USUARIO, CLAVE, BD);
   if($my->connect_errno){
       echo "<p>No se ha logrado la conexión</p>";
       exit(0);
   }else return $my;
}

De regreso a nuestro archivo makepdf.php, añadimos el archivo conectar.

require("conectar.php");

Dentro de nuestro objeto PDF, creamos un método llamado Body (Se puede llamar como uno desee)

function Body(){
            
}

Vamos a trabajar dentro del método Body. Lo primero será, crear la instancia del objeto mysqli para poder hacer nuestra sentencia preparada.

$my = conectObj();

Luego creamos nuestra cadena SQL.

$sql = "select nombre, sexo, edad, correo from contactos order by nombre";

Hacemos el statement correspondiente.

$stm = $my->prepare($sql);

Lo ejecutamos.

$stm->execute();

Creamos las variables que representan los campos de nuestra tabla.

$stm->bind_result($nombre, $sexo, $edad, $correo);

Almacenamos los resultados en dichas variables.

$stm->store_result();

Y buscamos conocer la cantidad de registros obtenidos.

$hay = $stm->num_rows;

Si la cantidad de registros obtenida es igual a cero, entonce mostramos un mensaje avisando que no tenemos nada que mostrar. Este mensaje ocupará 10 centímetros de ancho, 3 de alto, estará centrado. Además tendrá un borde (El primer 1) y hará un salto de línea (el segundo 1)

if($hay==0){
   $this->Cell(10, 3, "No hay registros que mostrar", 1, 1, 'C');
}

Pero si encontramos algo…

else{
}

Lo primero será colocar dentro de ese else, un salto de línea, eso lo logramos con el método Ln que, como ya mencionamos provoca un salto de renglón.

$this->Ln();

Luego cambiamos la fuente a tamaño 14, negrita.

$this->SetFont("Arial", 'B', 14);

Cambiamos el color de la fuente con el método SetTextColor que recibe como parámetro un valor en RGB.

$this->SetTextColor(62, 72, 204); // Este es azul marino

Ponemos los títulos de la tabla que queremos mostrar con anchos de 7, 3, 2 y 7 centímetros respectivamente.

$this->Cell(7,1,"Nombre", 1, 0, 'C');
$this->Cell(3,1,"Sexo", 1, 0, 'C');
$this->Cell(2,1,"Edad", 1, 0, 'C');
$this->Cell(7,1,"Correo", 1, 1, 'C');

Luego regresamos el color de la letra a Negro y el tipo de fuente a Normal.

$this->SetFont("Arial", '', 14);
$this->SetTextColor(0, 0, 0);

Después con un while, recorremos el fetch para extraer los valores de las variables, cuidando que el nombre se convierta a UTF8 para evitar caracteres extraños.

while($stm->fetch()){
   $nombre = utf8_decode($nombre);
   $this->Cell(7,1,$nombre, 1, 0, 'C');
   $this->Cell(3,1,$sexo, 1, 0, 'C');
   $this->Cell(2,1,$edad, 1, 0, 'C');
   $this->Cell(7,1,$correo, 1, 1, 'C');
}

No olvidemos cerrar el statement, justo donde termina el else.

$stm->close();

Ahora, invocamos la función Body, justo después de la llamada a AddPage.

$pdf->Body();

El resultado ya se ve bastante prometedor.

Como generar archivos PDF con PHP - CableNaranja

Colocando el pie de página para nuestro documento PDF

A nuestro objeto PDF, le añadiremos el método Footer, el cual es similar a Header. Es decir, no puede ser invocado directamente y se añade automáticamente al llamar al método AddPage.

function Footer(){
}

Lo primero que haremos, será colocar el pie de página usando el método SetY que permite establecer la posición en el eje Y. Al establecer este valor en negativo, le estamos pidiendo que lo haga de abajo hacia arriba. En este caso, serán 2 centímetros

$this->SetY(-2);

Luego, ponemos la fuente en cursiva y tamaño 10.

$this->SetFont("Arial", 'I', 10);

Y escribimos un texto lo más centrado posible. Al establecer la propiedad X de Cell en cero, le estamos diciendo que calcule la posición automáticamente.

$this->Cell(0, 1, "Como generar archivos PDF con PHP", 0, 0, 'C');

Hagamos una última prueba.

Como generar archivos PDF con PHP - CableNaranja

Guardemos nuestro PDF generado en un archivo

Para guardar el archivo o simplemente mostrarlo, disponemos del método Output. En un apartado anterior, lo llamamos sin argumentos ya que es la manera más sencilla de mostrar el documento. no obstante, este método tiene los siguientes argumentos.

  • Destino: Especifica como se debe tratar el PDF generado, utiliza los siguientes valores:
    • I: envía el fichero al navegador de forma que se usa la extensión (plug in) si está disponible. (Es el valor por defecto)
    • D: envía el fichero al navegador y fuerza la descarga del fichero con el nombre especificado por name.
    • F: guarda el fichero en un fichero local de nombre name.
    • S: devuelve el documento como una cadena.
  • Nombre: Es el nombre del archivo PDF
  • UTF8: Define si el nombre tiene la codificación UTF8 (true) o no (false) Y sólo funciona con los parámetros D e I.

En nuestro caso, haremos que el archivo aparte de mostrarse, se descargue, para ello, no modificaremos el Output que ya habíamos puesto, sino que lo llamaremos una segunda vez.

$pdf->Output("Documento Final.pdf", 'F');

Y este es el resultado final.

Como generar archivos PDF con PHP - CableNaranja

Si quieres probar el ejemplo, descarga el código fuente

¡Y con eso finalizamos este artículo! ¿Te ha resultado? Déjanos saber en los comentarios aquí abajo, en nuestra cuenta de twitter @cablenaranja7 o en nuestra página de facebook.

¡Comparte nuestro contenido!

Entradas relacionadas

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *