Solicitar firma manuscrita, crear PDF y subir a PHP

Subir PDF generado con html2pdf.js a PHP

Gracias a la librería html2pdf.js se puede crear un PDF en el navegador web usando solo JavaScript. En mi blog te enseñé a descargar ese PDF, pero ahora te enseñaré otra cosa: cómo enviar ese PDF a un servidor con PHP.

Solicitar firma manuscrita, crear PDF y subir a PHP
Solicitar firma manuscrita, crear PDF y subir a PHP

Vamos a combinar varias cosas, ya que el PDF también va a llevar una firma manuscrita. Veremos:

  1. Cómo solicitar la firma del usuario
  2. Enviar esa firma adjunta en el PDF
  3. Subir el PDF a PHP

Para esto, te recomiendo leer:

  1. Generando un PDF desde JS con html2pdf.js
  2. Obtener PDF de html2pdf.js y jsPDF como Blob
  3. Subir Blob de JS a PHP
  4. Solicitar firma de usuario con Canvas y JavaScript

Comencemos.

Diseño HTML

Además de importar las librerías y scripts de JavaScript, en el cuerpo del documento estarán los siguientes campos:

<input type="text" id="id" placeholder="ID">
<input type="text" id="nombre" placeholder="Nombre">
<input type="text" id="apellido" placeholder="Apellido">
<input type="text" id="direccion" placeholder="Dirección">
<p>Firma:</p>
<canvas id="canvas"></canvas>
<br>
<button id="btnLimpiar">Limpiar</button>
<button id="btnCrearPdf">Crear PDF</button>

Tenemos varios input para los datos del usuario, el canvas y los botones que sirven para limpiar el canvas y para crear el PDF.

Firma

El canvas o lienzo incrustado para que el usuario pueda colocar su firma en el documento PDF va a enviarse tal y como si fuera una imagen.

Por simplicidad, no explicaré cómo tomar la firma pues ya lo expliqué en otro tutorial, pero no te preocupes, ya que todo estará junto en el código completo de mi GitHub.

Ocultando botones

El PDF generado debe estar libre de los botones que limpian el canvas y crean el PDF. Para ello, al momento de generar el PDF, los botones son ocultados:

$ocultables.forEach($ocultable => {
   $ocultable.style.display = "none";
})

Después, para mostrarlos, se establece la propiedad display de style en inline.

Nota: $ocultables son un arreglo de botones que fueron recuperados con querySelector.

Generando PDF

Lo que sigue a continuación es generar el PDF a partir del HTML que tenemos, usando JavaScript y la librería html2pdf.js. La generación queda como se ve en el siguiente código.

Presta atención a que estoy esperando a que se resuelva la promesa que devuelve output para tener el PDF como Blob en la variable pdfComoBlob:

const $elementoParaConvertir = document.body; // <-- Aquí puedes elegir cualquier elemento del DOM
const pdfComoBlob = await html2pdf()
.set({
    margin: 1,
    filename: 'documento.pdf',
    image: {
        type: 'jpeg',
        quality: 0.98
    },
    html2canvas: {
        scale: 3, // A mayor escala, mejores gráficos, pero más peso
        letterRendering: true,
    },
    jsPDF: {
        unit: "in",
        format: "a3",
        orientation: 'portrait' // landscape o portrait
    }
})
.from($elementoParaConvertir)
.output("blob");

Ahora que tenemos los bytes del PDF o el PDF “crudo” podemos enviarlo al servidor de PHP usando fetch y FormData.

Subir PDF generado con JavaScript a PHP incluyendo firma

Creamos un FormData, adjuntamos los datos de los input así como el Blob del PDF y lo enviamos a recibir.php cuyo código veremos más adelante.

El código para subir el PDF a PHP queda así:

const formData = new FormData();
formData.append("pdf", pdfComoBlob);
formData.append("id", $id.value);
formData.append("nombre", $nombre.nombre);
formData.append("apellido", $apellido.apellido);
formData.append("direccion", $direccion.direccion);
//formData.append("otraVariable", "otroValor"); // En PHP la recuperamos como $_POST["otraVariable"]
const respuestaHttp = await fetch("./recibir.php", {
    body: formData,
    method: "POST",
});
const respuestaDelServidor = await respuestaHttp.text();

La función append de FormData toma como primer argumento una clave. Si el valor (segundo argumento) es un archivo, entonces estará en $_FILES en el lado de PHP, accediendo a él como $_FILES["claveUsadaEnFormData"] y si es un valor primitivo estará en $_POST["claveUsadaEnFormData"].

Fíjate que estoy esperando la respuesta del servidor como texto. Dicha respuesta será lo que el script de PHP (recibir.php) imprima ya sea con echo, printf, etcétera.

Recibir PDF con PHP

Es momento de recibir el PDF que trae la firma (como imagen) y los datos del usuario, todo generado con JavaScript. El código mostrado a continuación se encuentra en el archivo recibir.php.

El script es realmente sencillo, lo que hace es leer la variable id enviada desde el cliente y nombrar así el PDF, colocando todo en un directorio llamado firmas:

<?php
if (
    !isset($_POST["id"]) ||
    !isset($_POST["nombre"]) ||
    !isset($_POST["apellido"]) ||
    !isset($_POST["direccion"]) ||
    !isset($_FILES["pdf"])
) {
    exit("Faltan datos");
}
$archivoPdf = $_FILES["pdf"];
$id = $_POST["id"];
# Aquí podemos acceder a $_POST["nombre"], apellido, direccion
$directorio = "firmas";
if (!file_exists($directorio)) {
    mkdir($directorio);
}
$nombre = $id . ".pdf";
$ubicacion = $directorio . DIRECTORY_SEPARATOR . $nombre;
move_uploaded_file($archivoPdf["tmp_name"], $ubicacion);
echo "OK";

Para guardar el PDF se utiliza la función move_uploaded_file, misma que tiene que ver con la subida de archivos a PHP.

Más información

Solo quiero remarcar que podemos enviar cualquier cantidad de variables y archivos a PHP desde JavaScript, invocando a la función append del FormData cuantas veces sea necesario.

Si quisiéramos mostrar los valores del input en el PDF, en lugar de los input, podríamos colocar un párrafo y llenarlo tomando su valor del input antes de generar el documento, así como ocultando los input de manera similar a como lo hacemos con los botones. Todo esto con JavaScript.

El script de PHP puede devolver cualquier información y en cualquier formato. Yo he elegido devolverla como texto plano.

Poniendo todo junto

El código completo lo dejaré en mi GitHub. Vas a necesitar PHP con Apache o un servidor parecido. Basta con colocar el código en la carpeta pública, acceder a index.html y probar el código.

Recuerda que, en el lado de PHP, vas a necesitar permisos para escribir archivos. Esto depende de tu servidor, proveedor de servicios y configuración en general.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario