Resumen: generar una factura PDF con PHP, es decir, un ticket, recibo, boleta o invoice que tenga detalles de un cliente, del emisor, número de factura, fecha y productos que se venden, así como el total con impuestos y descuento.
Para generar la factura vamos a usar la librería dompdf que convierte HTML a un PDF nativo. Aunque por el momento será estática, puedes usar más tarde una base de datos con PHP.
Como lo dije, vamos a usar el lenguaje PHP para generar este comprobante. Comenzamos definiendo algunos datos que irán dentro de nuestra plantilla.
Si te fijas tengo un arreglo de productos así como el descuento aplicado y el impuesto.
<?php
$cliente = "Luis Cabrera Benito";
$remitente = "Luis Cabrera Benito";
$web = "https://parzibyte.me/blog";
$mensajePie = "Gracias por su compra";
$numero = 1;
$descuento = 0;
$porcentajeImpuestos = 16;
$productos = [
[
"precio" => 50,
"descripcion" => "Procesador AMD Ryzen 7",
"cantidad" => 1,
],
[
"precio" => 800,
"descripcion" => "Tarjeta de vídeo",
"cantidad" => 2,
],
];
$fecha = date("Y-m-d");
Obviamente estos datos pueden cambiar o venir de cualquier lugar. Ahora vamos a maquetar la factura.
Voy a utilizar Bootstrap 3 para diseñar la factura PDF; aunque ya existe la versión 4, probé con la misma y algunas cosas de la alineación fallaban, así que usaremos la 3, cosa que no afecta en absoluto, pues no estamos usando el estilo para la web, sino para el PDF.
Comenzamos con el encabezado, en el mismo incluimos la hoja de estilos de Bootstrap.
<!DOCTYPE html>
<html lang="es">
<head>
<link rel="stylesheet" href="./bs3.min.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Factura</title>
</head>
Ahora definimos el inicio de la factura en donde estará un logotipo, la fecha y el número de factura:
<div class="row">
<div class="col-xs-10 ">
<h1>Factura</h1>
</div>
<div class="col-xs-2">
<img class="img img-responsive" src="./parzibyte.jpg" alt="Logotipo">
</div>
</div>
<hr>
<div class="row">
<div class="col-xs-10">
<h1 class="h6"><?php echo $remitente ?></h1>
<h1 class="h6"><?php echo $web ?></h1>
</div>
<div class="col-xs-2 text-center">
<strong>Fecha</strong>
<br>
<?php echo $fecha ?>
<br>
<strong>Factura No.</strong>
<br>
<?php echo $numero ?>
</div>
</div>
En la línea 6 tenemos la imagen o logotipo. Después agregamos el cliente con el remitente:
<div class="row text-center" style="margin-bottom: 2rem;">
<div class="col-xs-6">
<h1 class="h2">Cliente</h1>
<strong><?php echo $cliente ?></strong>
</div>
<div class="col-xs-6">
<h1 class="h2">Remitente</h1>
<strong><?php echo $remitente ?></strong>
</div>
</div>
Más tarde, agregamos la lista de productos. Creamos la tabla y dibujamos la descripción, cantidad y total. Al final de la tabla colocamos la suma de algunas cosas y desglosamos los datos:
<div class="row">
<div class="col-xs-12">
<table class="table table-condensed table-bordered table-striped">
<thead>
<tr>
<th>Descripción</th>
<th>Cantidad</th>
<th>Precio unitario</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php
$subtotal = 0;
foreach ($productos as $producto) {
$totalProducto = $producto["cantidad"] * $producto["precio"];
$subtotal += $totalProducto;
?>
<tr>
<td><?php echo $producto["descripcion"] ?></td>
<td><?php echo number_format($producto["cantidad"], 2) ?></td>
<td>$<?php echo number_format($producto["precio"], 2) ?></td>
<td>$<?php echo number_format($totalProducto, 2) ?></td>
</tr>
<?php }
$subtotalConDescuento = $subtotal - $descuento;
$impuestos = $subtotalConDescuento * ($porcentajeImpuestos / 100);
$total = $subtotalConDescuento + $impuestos;
?>
</tbody>
<tfoot>
<tr>
<td colspan="3" class="text-right">Subtotal</td>
<td>$<?php echo number_format($subtotal, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">Descuento</td>
<td>$<?php echo number_format($descuento, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">Subtotal con descuento</td>
<td>$<?php echo number_format($subtotalConDescuento, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">Impuestos</td>
<td>$<?php echo number_format($impuestos, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">
<h4>Total</h4></td>
<td>
<h4>$<?php echo number_format($total, 2) ?></h4>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
La tabla es dibujada de manera dinámica, así que si se aumentan los productos, la tabla se refrescará automáticamente.
Para terminar, agregamos un pie:
<div class="row">
<div class="col-xs-12 text-center">
<p class="h5"><?php echo $mensajePie ?></p>
</div>
</div>
Nuestro diseño HTML está listo, es un HTML generado dinámicamente. Ahora vamos a generar una factura PDF con PHP a través de la salida de esto.
Si visitamos la página y la renderizamos como un HTML simple, vemos esto:
Recuerda que el código completo es el siguiente:
<?php
$cliente = "Luis Cabrera Benito";
$remitente = "Luis Cabrera Benito";
$web = "https://parzibyte.me/blog";
$mensajePie = "Gracias por su compra";
$numero = 1;
$descuento = 0;
$porcentajeImpuestos = 16;
$productos = [
[
"precio" => 50,
"descripcion" => "Procesador AMD Ryzen 7",
"cantidad" => 1,
],
[
"precio" => 800,
"descripcion" => "Tarjeta de vídeo",
"cantidad" => 2,
],
];
$fecha = date("Y-m-d");
?>
<!DOCTYPE html>
<html lang="es">
<head>
<link rel="stylesheet" href="./bs3.min.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Factura</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-xs-10 ">
<h1>Factura</h1>
</div>
<div class="col-xs-2">
<img class="img img-responsive" src="./parzibyte.jpg" alt="Logotipo">
</div>
</div>
<hr>
<div class="row">
<div class="col-xs-10">
<h1 class="h6"><?php echo $remitente ?></h1>
<h1 class="h6"><?php echo $web ?></h1>
</div>
<div class="col-xs-2 text-center">
<strong>Fecha</strong>
<br>
<?php echo $fecha ?>
<br>
<strong>Factura No.</strong>
<br>
<?php echo $numero ?>
</div>
</div>
<hr>
<div class="row text-center" style="margin-bottom: 2rem;">
<div class="col-xs-6">
<h1 class="h2">Cliente</h1>
<strong><?php echo $cliente ?></strong>
</div>
<div class="col-xs-6">
<h1 class="h2">Remitente</h1>
<strong><?php echo $remitente ?></strong>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<table class="table table-condensed table-bordered table-striped">
<thead>
<tr>
<th>Descripción</th>
<th>Cantidad</th>
<th>Precio unitario</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php
$subtotal = 0;
foreach ($productos as $producto) {
$totalProducto = $producto["cantidad"] * $producto["precio"];
$subtotal += $totalProducto;
?>
<tr>
<td><?php echo $producto["descripcion"] ?></td>
<td><?php echo number_format($producto["cantidad"], 2) ?></td>
<td>$<?php echo number_format($producto["precio"], 2) ?></td>
<td>$<?php echo number_format($totalProducto, 2) ?></td>
</tr>
<?php }
$subtotalConDescuento = $subtotal - $descuento;
$impuestos = $subtotalConDescuento * ($porcentajeImpuestos / 100);
$total = $subtotalConDescuento + $impuestos;
?>
</tbody>
<tfoot>
<tr>
<td colspan="3" class="text-right">Subtotal</td>
<td>$<?php echo number_format($subtotal, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">Descuento</td>
<td>$<?php echo number_format($descuento, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">Subtotal con descuento</td>
<td>$<?php echo number_format($subtotalConDescuento, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">Impuestos</td>
<td>$<?php echo number_format($impuestos, 2) ?></td>
</tr>
<tr>
<td colspan="3" class="text-right">
<h4>Total</h4></td>
<td>
<h4>$<?php echo number_format($total, 2) ?></h4>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="row">
<div class="col-xs-12 text-center">
<p class="h5"><?php echo $mensajePie ?></p>
</div>
</div>
</div>
</body>
</html>
Lo que resta es convertirlo a PDF.
Finalmente usamos el truco que mostré en el post de dompdf con PHP y obtenemos la salida del documento. Hacemos lo siguiente:
<?php
include_once "./vendor/autoload.php";
use Dompdf\Dompdf;
$dompdf = new Dompdf();
ob_start();
include "./factura.php";
$html = ob_get_clean();
$dompdf->loadHtml($html);
$dompdf->render();
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=factura.pdf");
echo $dompdf->output();
Al visitar la página se muestra un documento PDF que se ve así:
PD: ya sé que decir documento PDF es redundante pues PDF es Portable Document Format, pero me gusta llamarlo así 🙂
Con esto podemos generar facturas dinámicas, enviar el documento por correo, guardarlo en el disco duro, descargarlo, etcétera.
Recuerda que ya expliqué el uso de dompdf, si no entiendes bien lo expuesto aquí, te recomiendo encarecidamente que lo leas.
Te dejo un enlace para aprender más sobre PHP. Por cierto, si quieres puedes ver el documento PDF generado.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.
Ver comentarios
buenos dias, hevisto lo de pdf
necesito producir un tiquete pos desde una tabla mysql donde sera llamada con php, espero su amable respuesta
ademas necesito un soporte en php nativo
muy amable, gracias
Buenos días. Claro que sí, estoy a su servicio en https://parzibyte.me/#contacto o en el correo parzibyte (arroba) gmail.com
Muchas gracias por el aporte amigo
Abra una forma de colocar una marca de agua en el documento PDF realizado?
Hola. Gracias por sus comentarios. Si tiene alguna consulta, solicitud de creación de un programa o solicitud de cambio de software estoy para servirle en https://parzibyte.me/#contacto
Saludos!
Saludos, es la primera vez que veo tu blog y me parece muy bueno. Solo una duda, yo nunca he usado Bootrap así que no se dónde puedo encontrar el CSS para probar el ejemplo. Tienes la url completa de la hoja de estilos? Gracias.
Hola. Puede buscar en la página oficial del proyecto.
Saludos!
Hola, estoy probando su Script, y funciona perfectamente, salvo '', que no consigo encontrarlo...
hableme tambien de sus tarifas para posible colaboración..
Gracias por todo...
No entiendo
Gracias por el aporte , lo pude adaptar a mi proyecto DJANGO , se me hacia dificir el diseno de la factura me salvo la vida.
Me da gusto que le haya funcionado
Saludos! :)
Excelente aporte amigo, muchas gracias, hasta en foros en ingles dice que Dompdf no acepta bootstrap, pero es B4 que no es soportado. Agradecido!!
Gracias por el dato, la verdad es que no sabía, y al probar con BS3 funcionó así que así lo dejé.
Le invito a seguirme y compartir para estar al tanto de mis aportes :)
excelente aporte, muchas gracias!