Convertir HTML en PDF, rellenar plantillas, firmar documentos o ensamblar informes multipágina es una necesidad común en proyectos PHP. La “mejor” librería no es única: depende del caso de uso (HTML complejo, rendimiento, firma digital, PDF/A, manipulación avanzada, presupuesto, etc.). Este artículo repasa las opciones más utilizadas —dompdf, mPDF, TCPDF, FPDF, HTML2PDF, PDFlib, SetaPDF— y añade alternativas modernas basadas en motores externos (wkhtmltopdf, headless Chrome/Browsershot) y en FPDI para importar/mezclar PDFs. Al final, se ofrecen recomendaciones por escenario.
Resumen ejecutivo (qué elegir según el caso)
- HTML/CSS “estándar” (facturas, albaranes, informes):
mPDF o dompdf. mPDF suele rendir mejor con textos largos, RTL y tablas; dompdf destaca por su facilidad y comunidad enorme. - HTML “pixel perfect” con CSS avanzado (flex, grid, fuentes web, SVG complejo):*
wkhtmltopdf (wrapper PHP como mikehaertl/phpwkhtmltopdf) o Browsershot (Chrome headless). Renderizan como un navegador real. Ojo: requieren binarios externos. - PDF “desde cero” a alta velocidad, con control fino de dibujo (sin HTML):
TCPDF (open source) o PDFlib (comercial, muy potente y rápida). - Firmas digitales, certificados, PDF/A, manipulación avanzada (separar/unir, sellos, campos de formulario):
SetaPDF (comercial, módulos específicos) o TCPDF para firmas básicas. - Importar páginas de PDFs existentes y escribir encima (sellado, numeración, watermarks):
FPDI (junto con FPDF/TCPDF/mPDF).
*Nota sobre CSS Grid/Flex: los motores clásicos PHP-HTML tienen soporte parcial o nulo; para fidelidad total conviene un motor tipo navegador (wkhtmltopdf/Chrome).
Comparativa ampliada (visión general)
La tabla incluye las columnas solicitadas y algunas adicionales clave para elegir (licencia, soporte CSS/HTML, PDF/A, firma, RTL, imágenes/SVG y notas). Las versiones mínimas de PHP pueden variar por release; conviene consultar el
composer.json
de cada proyecto en producción.
Librería | Código abierto | Basado en HTML | OO | Composer | Documentación | Dependencias clave | Licencia | Soporte CSS/HTML | RTL/Idiomas complejos | PDF/A / Firma | Imágenes/SVG | Notas de uso |
---|---|---|---|---|---|---|---|---|---|---|---|---|
dompdf | Sí | Sí | Sí | Sí | Buena | PHP 7.x/8.x, ext-dom , ext-mbstring , php-font-lib , php-svg-lib | MIT | CSS 2.1 + parte de CSS3; HTML5 parcial | RTL razonable | Sin PDF/A nativo / firma no | SVG básico | Fácil de integrar; fidelidad buena para maquetaciones clásicas. |
mPDF | Sí | Sí | Sí | Sí | Buena | PHP 7.x/8.x, ext-mbstring , ext-gd | GPL | CSS 2.1 + HTML5 parcial, tablas muy robustas | Muy buen RTL (árabe/hebreo) | PDF/A-1b/2b (perfil), firma básica | Imágenes + SVG parcial | Suele rendir mejor en documentos extensos y RTL. |
TCPDF | Sí | Parcial (HTML limitado) | Sí | Sí | Regular | PHP 7.x/8.x | LGPL | HTML básico (sin CSS complejo) | Correcto | Firma digital, barcodes, QR | Imágenes + SVG | Muy estable y rápido dibujando; menos “bonito” con HTML. |
FPDF | Sí | No | Sí | No (manual) | Regular | PHP 5.x+ (simple) | LGPL | No aplica | – | Sin PDF/A/firma (extensiones aparte) | JPG/PNG | Minimalista; ideal para PDFs sencillos por código. |
HTML2PDF (spipu) | Sí | Sí | Sí | Sí | Buena | PHP 5.6+, ext-gd , ext-mbstring | LGPL | Parser propio + TCPDF | Parcial | Depende de TCPDF | Imágenes | Sencilla; proyecto maduro, menos activa que mPDF/dompdf. |
PDFlib | No | No | Sí | No | Muy buena | Extensión/componente PDFlib | Comercial | API de dibujo (sin HTML) | – | Firma/funciones avanzadas | Alto | Muy rápida y completa; coste de licencia. |
SetaPDF (Setasign) | No | No | Sí | Sí | Muy buena | Módulos PHP (composer) | Comercial | No render HTML | – | PDF/A, firma, formularios, reparación | Alto | Suite modular de alto nivel para manejo de PDF. |
wkhtmltopdf (vía wrappers PHP) | Binario externo | Sí (WebKit) | – | Sí (wrapper) | Buena | Binario wkhtmltopdf | LGPL (binario); wrapper MIT | Motor navegador (CSS amplio) | Sí | Depende | Excelente | Fidelidad de maquetación; requiere instalar binario/servidor. |
Browsershot (Spatie, Chrome headless) | Wrapper | Sí (Chrome) | – | Sí | Buena | Node.js + Chrome/Chromium | MIT | Motor navegador (CSS moderno) | Sí | Depende | Excelente | Pixel-perfect; dependencia Node/Chrome. |
FPDI (Setasign/fpdi) | Sí (núcleo) | No | Sí | Sí | Buena | Requiere FPDF/TCPDF/mPDF | MIT + add-ons | – | – | No (núcleo); módulos aparte | – | Importar/ensamblar PDFs existentes; no renderiza HTML. |
“Parcial” en HTML/CSS indica soporte básico (párrafos, tablas, estilos simples). Para grid, flex, @media y efectos complejos, usar motores tipo navegador.
Ventajas y límites de cada enfoque
1) Librerías HTML→PDF puras en PHP (dompdf, mPDF, HTML2PDF)
Ventajas: instalación simple, despliegue sin binarios externos, integraciones populares (Laravel, Symfony), buen equilibrio calidad/rendimiento en informes, facturas y listados.
Límites: CSS moderno y maquetaciones “pixel perfect” pueden no replicarse al 100 %. SVG y fuentes variables tienen matices.
dompdf destaca por la curva de entrada corta y comunidad; mPDF por robustez en tablas, RTL y perfiles PDF/A básicos.
2) Render “como un navegador” (wkhtmltopdf / Chrome headless)
Ventajas: fidelidad de CSS/HTML muy alta, soporte de webfonts, SVG y maquetaciones complejas idénticas al navegador.
Límites: requiere instalar binarios (wkhtmltopdf o Chrome/Chromium), planificar recursos (memoria/tiempo), y gestionar seguridad (invocación del binario desde PHP).
Para catálogos, informes gráficos, diseños marketing o cualquier “lo que ves en el navegador, tal cual en PDF”, son la opción más consistente.
3) Dibujo por API (TCPDF, FPDF, PDFlib)
Ventajas: control al milímetro, rendimiento muy alto, sin convertir HTML; firmas, barcodes, marcadores, etc.
Límites: requiere maquetar por código (más tiempo), curva de aprendizaje, y es menos flexible para cambios de diseño a última hora.
TCPDF es el “tanque” open source; PDFlib es referencia comercial en rendimiento y herramientas profesionales.
4) Manipulación/ensamblado y firma (SetaPDF, FPDI)
SetaPDF cubre escenarios avanzados: PDF/A, firma/validación, formularios, redacción (redaction), stamping, split/merge, reparación. FPDI es excelente para importar PDFs (por ejemplo, usar una plantilla oficial) y escribir encima con FPDF/TCPDF/mPDF.
Casos de uso y recomendaciones concretas
- Facturas y documentos administrativos (logos, tablas, totales):
mPDF (tablas/RTL) o dompdf (facilidad). Si el diseño es muy exigente, wkhtmltopdf. - Informes dinámicos con páginas largas (mucho texto, numeración, TOC):
mPDF o TCPDF (si no necesitas HTML avanzado). - Certificados, contratos con firma, PDF/A para archivo:
SetaPDF (mejor soporte de firma/PDF/A), ó TCPDF si vale una firma básica. - Reetiquetar PDFs oficiales (plantillas externas):
FPDI + FPDF/TCPDF/mPDF. - Catálogos y brochures con diseño web replicado al 100 %:
Browsershot (Chrome) o wkhtmltopdf.
Ejemplos mínimos (orientativos)
dompdf (HTML→PDF sencillo):
use Dompdf\Dompdf;
require 'vendor/autoload.php';
$html = '<h1>Factura #2025-001</h1><p>Total: 1.245,50 €</p>';
$dompdf = new Dompdf([
'isRemoteEnabled' => true, // permitir imágenes remotas
'defaultFont' => 'DejaVu Sans'
]);
$dompdf->loadHtml($html, 'UTF-8');
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$dompdf->stream('factura-2025-001.pdf', ['Attachment' => true]);
Lenguaje del código: PHP (php)
mPDF (tablas, RTL, fuentes TTF):
$mpdf = new \Mpdf\Mpdf(['mode' => 'utf-8', 'format' => 'A4']);
$mpdf->WriteHTML('<style>table{border-collapse:collapse}td,th{border:1px solid #ccc;padding:6px}</style>');
$mpdf->WriteHTML('<table><tr><th>Artículo</th><th>Importe</th></tr><tr><td>Servicio</td><td>1.245,50 €</td></tr></table>');
$mpdf->Output('informe.pdf', 'I');
Lenguaje del código: HTML, XML (xml)
TCPDF (dibujo directo):
$pdf = new TCPDF();
$pdf->AddPage();
$pdf->SetFont('dejavusans','',12);
$pdf->Cell(0,10,'Informe mensual',0,1);
$pdf->Output('informe.pdf','I');
Lenguaje del código: PHP (php)
wkhtmltopdf (wrapper mikehaertl/phpwkhtmltopdf):
use mikehaertl\wkhtmlto\Pdf;
$pdf = new Pdf('<h1>Catálogo</h1><p>Diseño web a PDF</p>');
$pdf->binary = '/usr/local/bin/wkhtmltopdf';
$pdf->setOptions(['enable-local-file-access' => true]);
if (!$pdf->send('catalogo.pdf')) {
error_log($pdf->getError());
}
Lenguaje del código: PHP (php)
Tabla detallada original (ampliada con notas de compatibilidad)
Librería | Código abierto | Basado en HTML | OO | Composer | Documentación | Dependencias |
---|---|---|---|---|---|---|
dompdf | Sí | Sí | Sí | Sí | Buena | PHP 7.x/8.x; ext-dom , ext-mbstring , php-font-lib , php-svg-lib |
FPDF | Sí | No | Sí | No | Regular | Sin extensiones; muy ligera |
HTML2PDF | Sí | Sí | Sí | Sí | Buena | PHP ≥5.6; ext-gd , ext-mbstring (usa TCPDF) |
mPDF | Sí | Sí | Sí | Sí | Buena | ext-mbstring , ext-gd ; PHP 7.x/8.x |
TCPDF | Sí | No (HTML limitado) | Sí | Sí | Regular | PHP 7.x/8.x |
PDFlib | No | No | Sí | No | Muy buena | Extensión/SDK PDFlib (comercial) |
SetaPDF | No | No | Sí | Sí | Muy buena | Módulos Setasign (comercial) |
Añadidos recomendados:
Librería | Código abierto | Basado en HTML | OO | Composer | Documentación | Dependencias |
---|---|---|---|---|---|---|
wkhtmltopdf (wrapper PHP) | Parcial (wrapper sí) | Sí (WebKit) | – | Sí (wrapper) | Buena | Binario wkhtmltopdf instalado en el sistema |
Browsershot (Spatie) | Sí | Sí (Chrome) | – | Sí | Buena | Node.js + Chrome/Chromium (Puppeteer) |
FPDI | Núcleo sí | No | Sí | Sí | Buena | Depende de FPDF/TCPDF/mPDF (importa páginas de PDF) |
Buenas prácticas (para evitar sorpresas en producción)
- Fuentes y Unicode: use DejaVu Sans/Noto y subconjunto de fuentes cuando sea posible para reducir peso.
- Imágenes: optimizar a 300 ppp como máximo; prefiera JPG para fotos y PNG/SVG para gráficos.
- Paginación y saltos: pruebe contenidos “largos” y tablas multipágina; ajuste CSS (
page-break-inside
,page-break-after
). - Tiempo y memoria: establezca timeouts y memory_limit razonables; renderizar HTML complejo puede ser costoso.
- Determinismo: para documentos legales, evite depender de recursos remotos (CSS, fuentes); incruste todo.
- Pruebas visuales: genere “goldens” (PDF de referencia) y compare en CI para detectar cambios de render entre versiones.
- Seguridad: jamás renderice HTML no confiable sin sanitizar; evite rutas de archivo arbitrarias.
Conclusión
- Si el objetivo es HTML a PDF fiable y rápido, con buen soporte de tablas y textos complejos, mPDF es el “generalista” más sólido.
- Si prima la sencillez y una comunidad gigante, dompdf cumple con nota en la mayoría de facturas e informes.
- Si se necesita fidelidad “como en el navegador”, wkhtmltopdf o Browsershot son la vía correcta (asuma la dependencia del binario).
- Para manipulación avanzada, firma, PDF/A y flujos empresariales exigentes, SetaPDF (comercial) o PDFlib.
- Para plantillas PDF existentes (sellos, numeración), FPDI es la herramienta adecuada.
- Y si se quiere control absoluto y rendimiento, TCPDF o PDFlib dibujando por API son imbatibles.
La mejor librería, en definitiva, es la que minimiza el coste de mantenimiento en su caso: equilibre fidelidad, rendimiento, características legales (PDF/A/firma) y operativa (binarios, hosting, CI/CD) antes de decidir.