Tutorial para Generar PDF con un Logo utilizando un API REST en PHP (PDO, POO y MySQL)

 


En esta entrada del blog, detallaré un tutorial en el cual aprenderás a crear una API REST en PHP que genere un PDF con un logo personalizado, utilizando PDO para la conexión con MySQL, bajo un enfoque de Programación Orientada a Objetos (POO). Si quieres repasar o aprender antes como crear un API REST con PHP de una forma muy fácil, checa esta entrada del blog.

Esta imagen representa la funcionalidad de la API REST:


Ahora bien, comenzaremos indicando los requisitos previos a este ejemplo:
  • PHP 8.0+ (con extensiones PDOmbstringgd)

  • MySQL 5.7+ (o MariaDB)

  • Composer (para instalar dependencias)

  • Servidor web (Apache, Nginx o PHP built-in server)

  • Biblioteca TCPDF (para generación de PDFs)

  • El editor de tu preferencia, yo utilizo Visual Studio Code.

Paso 1: Configurar la Base de Datos

El primer paso consiste en crear una tabla en nuestra base de datos MySQL para almacenar registros que se incluirán en el PDF. Aquí puedes crear la base de datos con el nombre que quieras, a la tabla la nombré pdf_api. La tabla contendrá 4 campos, el id auto incrementable, el titulo de nuestro PDF, el contenido del PDF que crearemos y como extra la fecha de creación del archivo.


CREATE DATABASE pdf_api;
USE pdf_api;

CREATE TABLE documentos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    titulo VARCHAR(100) NOT NULL,
    contenido TEXT NOT NULL,
    fecha_creacion TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Paso 2: Estructura del Proyecto

Esta estructura organiza el proyecto en carpetas lógicas para que sea más fácil de mantener. La carpeta config guarda la conexión a la base de datos, controllers maneja la generación de PDFs, y models interactúa con los datos. La carpeta vendor almacena librerías externas como TCPDF, mientras que index.php es el archivo principal que recibe las peticiones. Además, logo.png es la imagen que se usará en los PDFs. Todo está separado para que el código sea más ordenado y escalable.

Organiza tu proyecto así:

/pdf-api/
│── config/
│   └── Database.php          # Conexión PDO a MySQL
│── controllers/
│   └── PdfController.php     # Lógica para generar PDF
│── models/
│   └── DocumentoModel.php    # Operaciones con la DB
│── vendor/                   # Dependencias (TCPDF)
│── index.php                 # Punto de entrada API
│── logo.png                  # Logo para el PDF

Paso 3: Instalar la librería TCPDF

Este paso consiste en instalar TCPDF, una librería de PHP que permite generar archivos PDF de forma sencilla. Para instalarla, solo debes ejecutar el comando composer require tecnickcom/tcpdf en la terminal. Composer (el gestor de dependencias de PHP) se encargará de descargar la librería y guardarla automáticamente en la carpeta /vendor/ de tu proyecto. Así, podremos usarla en el código para crear PDFs sin tener que programar todo desde cero. Es una forma rápida y eficiente de agregar funcionalidades avanzadas a cualquier aplicación web que desarrollemos.

Ejecuta en la terminal:

composer require tecnickcom/tcpdf

Paso 4: Configurar la Conexión PDO (Database.php)

Este código configura la conexión a la base de datos MySQL usando PDO (una forma segura de trabajar con bases de datos en PHP). La clase Database guarda los datos de conexión (servidor, nombre de la base, usuario y contraseña) y tiene un método getConnection() que intenta conectarse. Si hay éxito, devuelve la conexión lista para usarse, pero si falla, mostrará un error y dentendrá la ejecución. Esto permite acceder a la base de datos de manera sencilla y segura desde cualquier parte del proyecto. Recuerda la entrada en la que explico algo más de PDO en este blog.

(Importante: En un entorno real, de producción, la recomendación que te hago es que uses variables de entorno o un archivo de configuración aparte para no exponer datos sensibles como el usuario y la contraseña directamente en el código).

class Database {
    private $host = 'localhost';
    private $db_name = 'pdf_api';
    private $username = 'root';
    private $password = '';
    private $conn;

    public function getConnection() {
        $this->conn = null;
        try {
            $this->conn = new PDO(
                "mysql:host={$this->host};dbname={$this->db_name}",
                $this->username,
                $this->password
            );
            $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            die("Error de conexión: " . $e->getMessage());
        }
        return $this->conn;
    }

}

Paso 5: Crear el Modelo (DocumentoModel.php)

Este código crea el DocumentoModel, una clase que se encarga de interactuar con la base de datos para manejar los documentos PDF que vayamos a generar. Primero, incluye la conexión a la base de datos (el Database.php que configuramos en el paso 4 de este tutorial). Luego, en su constructor, establece la conexión usando PDO.

El método obtenerDocumento($id) busca un documento por su ID:

  • Prepara una consulta SQL segura (evitando inyecciones SQL gracias a PDO).

  • Ejecuta la consulta con el ID proporcionado.

  • Devuelve los datos del documento en forma de array asociativo.

Este modelo (recuerda que trabajamos con MVC, busca la entrada en el blog donde explico esto) sirve como intermediario entre la aplicación y la base de datos, haciendo que sea fácil y seguro recuperar información de documentos cuando se necesite.

(Importante: podrías añadir más métodos como crearDocumento() o eliminarDocumento() si tu API requiere esas funcionalidades, para practicar podrías hacerlo).

require_once __DIR__ . '/../config/Database.php';

class DocumentoModel {
    private $db;

    public function __construct() {
        $this->db = (new Database())->getConnection();
    }

    public function obtenerDocumento($id) {
        $query = "SELECT * FROM documentos WHERE id = ?";
        $stmt = $this->db->prepare($query);
        $stmt->execute([$id]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
}

Paso 6: Crear el Controlador (PdfController.php)

Este paso crea el PdfController, que es el encargado de generar el PDF a partir de los datos de la base de datos. Primero, debemos importar las dependencias necesarias: el DocumentoModel (para obtener los datos) y TCPDF (para crear el PDF).

El método generarPdf($documentoId) hace lo siguiente:

  • Busca el documento en la base de datos usando el modelo. Si no existe, devuelve un error 404.

  • Crea un nuevo PDF con TCPDF, añade una página y configura la fuente.

  • Inserta el logo (logo.png) en la esquina superior izquierda.

  • Añade el título y contenido del documento, usando estilos diferentes para cada uno.

  • Fuerza la descarga del PDF con el nombre documento.pdf.

Este controlador actúa como intermediario: toma los datos del modelo, los formatea en un PDF profesional y los envía al usuario para descargar.

(Importante: Si quieres guardar el PDF en el servidor en lugar de enviarlo al cliente, puedes cambiar 'D' por 'F' y especificar una ruta de guardado, te recomiendo hacerlo como práctica).

require_once __DIR__ . '/../models/DocumentoModel.php';
require_once __DIR__ . '/../vendor/autoload.php'; // TCPDF

class PdfController {
    public function generarPdf($documentoId) {
        $model = new DocumentoModel();
        $documento = $model->obtenerDocumento($documentoId);

        if (!$documento) {
            http_response_code(404);
            echo json_encode(["error" => "Documento no encontrado"]);
            return;
        }

        // Crear PDF con TCPDF
        $pdf = new TCPDF();
        $pdf->AddPage();
        $pdf->SetFont('helvetica', 'B', 16);

        // Insertar logo
        $pdf->Image(__DIR__ . '/../logo.png', 10, 10, 30);

        // Título y contenido
        $pdf->Cell(0, 10, $documento['titulo'], 0, 1);
        $pdf->SetFont('helvetica', '', 12);
        $pdf->MultiCell(0, 10, $documento['contenido']);

        // Guardar o descargar
        $pdf->Output('documento.pdf', 'D'); // 'D' = Descarga forzada
    }
}

Paso 7: Implementar la API (index.php)

En este paso el archivo index.php es el encargado de recibir las peticiones web y activar todo el proceso. Cuando alguien visita la página, lo primero que hace es verificar si se envió un ID de documento por la URL (por ejemplo: tusitio.com/?id=5). Si no se proporciona ningún ID, inmediatamente devuelve un error en formato JSON diciendo "Falta el ID del documento".

Si el ID está presente, el sistema pasa a trabajar con el PdfController, que es como el jefe de operaciones. Este controlador toma el ID, busca la información del documento en la base de datos a través del DocumentoModel, y si todo existe correctamente, usa la librería TCPDF para armar un PDF profesional con el logo de la empresa, el título del documento y su contenido.

Finalmente, el PDF generado se descarga automáticamente en el navegador del usuario. Todo el proceso es rápido y automatizado: recibe una solicitud, verifica los datos, crea el documento y lo entrega. Si algo falla en el camino (como que el documento no exista), la API responde con un mensaje de error claro para que sepas qué salió mal. Es como una fábrica de PDFs que trabaja bajo demanda.

(Importante: En un proyecto real, de producción, podrías usar rutas más amigables como /generar-pdf/1 con un sistema de enrutamiento como SlimPHP o Laravel).

header("Content-Type: application/json");
require_once __DIR__ . '/controllers/PdfController.php'; // Obtener ID del documento desde la URL (ej: /generar-pdf?id=1) $documentoId = $_GET['id'] ?? null; if (!$documentoId) { http_response_code(400); echo json_encode(["error" => "ID de documento no proporcionado"]); exit; } // Generar PDF $pdfController = new PdfController(); $pdfController->generarPdf($documentoId);

Paso 8: Probar la API 

Este es el último paso, aquí te explico cómo probar que nuestra API de generación de PDF funcione correctamente. Primero, necesitamos datos de prueba en la base de datos, por lo que se inserta manualmente un documento de ejemplo usando el comando SQL proporcionado. Este comando crea un nuevo registro con un título ("Mi Primer PDF") y un contenido de texto demostrativo.

Una vez que tienes datos en la base de datos (específicamente un documento con ID=1), podemos probar la API accediendo a la URL http://localhost:8000/generar-pdf?id=1 desde el navegador o con herramientas como Postman. Al hacer esta petición, la API buscará el documento con ID 1 en la base de datos, generará un PDF con esa información (incluyendo el logo, título y contenido) y automáticamente iniciará la descarga del archivo PDF en nuestro dispositivo.

Esta prueba verifica que todos los componentes (base de datos, modelo, controlador y librería TCPDF) están funcionando correctamente juntos. Si todo está bien configurado, obtendremos un PDF descargable; si hay errores, se mostrarán mensajes que nos ayudarán a identificar dónde está el problema.

Inserta un registro en la base de datos:

INSERT INTO documentos (titulo, contenido) 
VALUES ('Mi Primer PDF', 'Este es un PDF generado desde una API REST en PHP.');

Accede desde el navegador o Postman:

http://localhost:8000/generar-pdf?id=1

Finalmente, el PDF se descargará automáticamente un PDF con nuestro logo y contenido. Con esta API, puedes generar PDFs personalizados con logos desde una base de datos MySQL usando PHP, PDO, POO y TCPDF. Ideal para facturas, reportes o documentos automatizados.


Es cuánto.

Si quieres citar este artículo en tu texto, documento, etc. puedes hacerlo de la siguiente forma:

Aguilar-Calderón, J. A. (8 de abril de 2025). Tutorial para Generar PDF con un Logo utilizando un API REST en PHP (PDO, POO y MySQL). ANOVA LAB MX. https://anovalabmx.blogspot.com/2025/04/tutorial-para-generar-pdf-con-un-logo.html

Comentarios

Mi foto
José Alfonso Aguilar
Mazatlán, Sinaloa, Mexico
Me gusta aprender y escribir sobre tecnología y desarrollo. Soy Ingeniero en Sistemas Computacionales, trabajo como Profesor-Investigador en la Facultad de Informática Mazatlán, de la Universidad Autónoma de Sinaloa. México. Me gusta combinar la docencia-investigación con el giro profesional del desarrollo de software y gestión de proyectos de innovación.

Entradas más populares de este blog

Historia y versiones de HTML (HyperText Markup Language)

Todo lo que debes saber sobre el Model-View Controller (MVC) para Aplicaciones Web

Stateful vs Stateless Design - ¿Cuál es la diferencia?