Plugin PDF

Plugin para imprimir PDF de manera silenciosa con JavaScript

Hoy vengo a presentarte un plugin que recién he creado. Se trata de un plugin para imprimir un archivo PDF de manera silenciosa, es decir, sin pedir confirmación al usuario.

El plugin no tiene costo y lo puedes usar gratis sin límite.

Este plugin expone una API REST para que se pueda imprimir un PDF sin confirmación usando JavaScript. Basta con hacer una petición HTTP GET a la ruta del plugin enviando el nombre del PDF y el nombre de la impresora. Vas a poder imprimir un PDF:

  1. Local, existente en la computadora a partir de su ubicación
  2. De internet, expuesto públicamente
  3. A partir de HTML
  4. A partir de su representación como base64

Lo mejor de esto es que puedes usar las impresoras virtuales que ofrece Windows, de este modo puedes hacer tus pruebas de manera ecológica.

A lo largo de este post te mostraré la documentación del plugin y todos los detalles del mismo.

Descargando herramientas

Para este tutorial vas a necesitar contar con:

  1. plugin_pdf_prod_32.exe o plugin_pdf_prod_64.exe el cual se descarga en: https://github.com/parzibyte/plugin-silent-pdf-print-examples/releases/latest
  2. PDFtoPrinter.exe el cual se descarga en: https://mendelson.org/pdftoprinter.html o en https://github.com/emendelson/pdftoprinter/blob/main/PDFtoPrinter.exe?raw=true

Nota: ninguna de las herramientas contiene malware, aunque los antivirus o sistemas lo detecten como tal. Es tu responsabilidad obligar al sistema a confiar en los programas y de ser necesario agregarlos a las excepciones.

También he notado que en ocasiones el navegador bloquea la descarga; de nuevo, es tu responsabilidad forzarla.

Una vez descargados, ejecuta plugin_pdf_prod_32.exe o plugin_pdf_prod_64.exe y deja a PDFtoPrinter.exe en el mismo directorio donde se encuentra el archivo que has ejecutado.

Prueba rápida

Para hacer una prueba rápida, abre tu navegador en http://localhost:8080/version y debe aparecer:

{"version":"0.3","plataforma":"Desktop PDF","sistemaOperativo":"windows"}

Si no te aparece ese mensaje exacto, asegúrate de haber ejecutado el plugin. Te recomiendo revisar todo de nuevo, ya que si no aparece ese mensaje no podrás imprimir el documento.

También fíjate que en plataforma debe decir Desktop PDF, ya que tengo otros plugins y si bien funcionan, no tienen que ver con este tutorial específico.

Imprimir archivo local

En este primer ejemplo veremos cómo imprimir un archivo local existente en la computadora a partir de su ruta absoluta, es decir, algo como C:\Users\TuUsuario\nombre.pdf.

Lo único que tienes que hacer para imprimir un PDF existente en la computadora es hacer una petición a http://localhost:8080 enviando los siguientes parámetros GET:

  • nombrePdf: una cadena indicando la ruta absoluta del PDF. Si el PDF está en la misma carpeta que el plugin, puedes simplemente indicar el nombre del PDF.
  • nombreImpresora: una cadena indicando el nombre de la impresora

Yo lo haré con fetch, y la función para imprimir queda así:

const imprimir = async () => {
    let nombrePdf = "Nombre o ubicación del PDF";
    nombrePdf = reemplazarEspaciosConEntidad(nombrePdf);
    const nombreImpresora = "Aquí va el nombre de tu impresora";
    const url = `http://localhost:8080/?nombrePdf=${nombrePdf}&impresora=${nombreImpresora}`;
    $estado.textContent = "Imprimiendo...";
    // Hacer petición...
    try {
        const respuesta = await fetch(url);
        // Si la respuesta es OK, entonces todo fue bien
        if (respuesta.status === 200) {
            $estado.textContent = "Impreso correctamente (salvo que se haya indicado un error por parte de PDFtoPrinter)";
            console.log("Impresión OK");
        } else {
            // Si no, decodificamos el mensaje para ver el error
            const mensaje = await respuesta.json();
            $estado.textContent = "Error imprimiendo: " + mensaje;
            console.log("Error: " + mensaje);
        }
    } catch (error) {
        $estado.textContent = "Error haciendo petición. Asegúrese de que el plugin se está ejecutando: " + error;
        console.log("Error: " + error);
    }
}

Si te fijas, simplemente es como visitar la URL http://localhost:8080/?nombrePdf=documento.pdf&nombreImpresora=NombreDeImpresora

Demostración en vivo: https://parzibyte.github.io/plugin-silent-pdf-print-examples/ruta_absoluta.html

Código completo: https://github.com/parzibyte/plugin-silent-pdf-print-examples/blob/main/ruta_absoluta.html.

Imprimiendo PDF remoto de internet por URL

Como te has dado cuenta, hasta este momento te enseñé cómo imprimir un PDF local. Pero puedes imprimir un PDF que esté en tu hosting o en un sitio de internet.

Por ejemplo, para imprimir un PDF de internet que está en https://parzibyte.github.io/plugin-silent-pdf-print-examples/ticket.pdf en la impresora Microsoft Print to PDF, haría una petición GET a la siguiente URL:

http://localhost:8080/url?impresora=Microsoft%20Print%20to%20PDF&urlPdf=https://parzibyte.github.io/plugin-silent-pdf-print-examples/ticket.pdf

Fíjate en que ahora la petición se hace a localhost:8080/url ya que cuando se hace a localhost:8080/ es para imprimir un PDF local. Los parámetros son impresora indicando el nombre de la impresora y urlPdf que indica la URL del PDF que se imprime.

Por poner otro ejemplo, si quisiera imprimir un PDF que está en localhost/archivos/mi_pdf.pdf en la impresora POS58 haría una petición a la siguiente URL:

http://localhost:8080/url?impresora=POS58&urlPdf=localhost/archivos/mi_pdf.pdf

Nota importante: no importa el sitio o dominio en donde esté el PDF que se va a imprimir de manera silenciosa desde la nube.

Veamos el código de la función para imprimir:

const imprimir = async () => {
    $estado.textContent = "Imprimiendo...";
    // Estos parámetros podrían venir de cualquier lugar
    const urlPDF = "http://url.del.pdf";
    const nombreImpresora = "Tu impresora";
    const url = `http://localhost:8080/url?urlPdf=${urlPDF}&impresora=${nombreImpresora}`;
    // Hacer petición...
    try {
        const respuesta = await fetch(url);
        // Si la respuesta es OK, entonces todo fue bien
        if (respuesta.status === 200) {
            $estado.textContent = "Impreso correctamente (salvo que se haya indicado un error por parte de PDFtoPrinter)";
            console.log("Impresión OK");
        } else {
            // Si no, decodificamos el mensaje para ver el error
            const mensaje = await respuesta.json();
            $estado.textContent = "Error imprimiendo: " + mensaje;
            console.log("Error: " + mensaje);
        }
    } catch (error) {
        $estado.textContent = "Error haciendo petición. Asegúrese de que el plugin se está ejecutando: " + error;
        console.log("Error: " + error);
    }
}

Lo único que es importante es que el mismo esté disponible de manera pública (que cualquiera que visite esa URL tenga acceso al mismo) ya que internamente el plugin va a descargarlo y luego imprimirlo; todo esto de manera silenciosa.

Prueba la demostración en vivo aquí: https://parzibyte.github.io/plugin-silent-pdf-print-examples/pdf_internet.html

Y el código lo puedes ver en: https://github.com/parzibyte/plugin-silent-pdf-print-examples/blob/main/pdf_internet.html

Documentación de la API

Este plugin crea un servidor web en localhost:8080 y expone dos rutas; una para imprimir un PDF local y otra para imprimir un PDF remoto.

Si invocas a http://localhost:8080/ los parámetros son:

  • nombrePdf: obligatorio, la ruta relativa o absoluta del documento PDF incluyendo extensión.
  • impresora: obligatorio, el nombre de la impresora en donde quieres imprimir el documento.
  • serial: opcional, serial del plugin en caso de que cuentes con uno
  • grados: opcional, rotar el PDF antes de imprimirlo. Debe ser múltiplo de 90

Si invocas a http://localhost:8080/url los parámetros son:

  • urlPdf: obligatorio, la ruta relativa o absoluta del documento PDF incluyendo extensión.
  • impresora: obligatorio, el nombre de la impresora en donde quieres imprimir el documento.
  • serial: opcional, serial del plugin en caso de que cuentes con uno
  • grados: opcional, rotar el PDF antes de imprimirlo. Debe ser múltiplo de 90

En una actualización he agregado la opción para imprimir un PDF a partir de su representación como base64.

Errores comunes

A continuación presento una lista de errores comunes que pueden aparecer al usar el plugin.

  • open archivo.pdf: Access is denied – Es porque el plugin no puede leer el archivo o porque el plugin no puede crear un archivo (seguramente es por falta de permisos, intente mover el plugin de ubicación y/o ejecutarlo como administrador)
  • PDFtoPrinter.exe: executable file not found in %PATH% – No ha copiado el archivo PDFtoPrinter.exe junto al plugin. Ambos deben estar en la misma carpeta.
  • “fork/exec PDFtoPrinter.exe: The system cannot find the file specified.”: El ejecutable PDFtoPrinter no está en la misma ubicación que el plugin
  • Printer name “Impresora” not found or argument “Impresora” is invalid: la impresora en la que intentas imprimir no existe.
  • “Read: xRefTable failed: pdfcpu: can’t find last xref section”: el PDF que intentas imprimir no es compatible con el plugin, ya sea porque estás enviado una base64 de algo que no es un PDF o de una versión de un PDF que no es compatible con el plugin. Asegúrate de que el PDF está codificado como base64 y su codificación es correcta.

Remover marca de agua de Parzibyte

Como te habrás dado cuenta, al momento de imprimir aparece una “marca de agua” con contenido y posición aleatorios. El plugin es totalmente gratis, pero debes respetar esa marca de agua con mis créditos.

Si quieres removerla, puedes contratar una licencia. El costo de la misma es de 150 MXN (pesos mexicanos) mensuales (un mes se toma como un período de 30 días).

Te invito a probar el plugin gratuito, y si te funciona en los lugares que necesitas entonces puedes contratar una licencia por los meses que creas convenientes haciendo el pago en https://parzibyte.me/blog/pagos-venta-software/ indicando el concepto y tu correo.

Igualmente luego de hacer el pago puedes contactarme en https://parzibyte.me/#contacto en caso de que olvides poner el concepto o no te haya contactado.

No olvides que lo único que hace la licencia es remover la marca de agua, no provee soporte técnico ni hace que funcione en lugares donde el plugin gratuito no funciona. Las condiciones que acepta al hacer el pago son:

  1. Lo único que hace la licencia es remover la marca de agua con mis créditos
  2. Enviaré la licencia en un plazo de hasta 24 horas una vez recibido el pago.
  3. Una vez enviada la licencia (sin importar si usted ha revisado sus mensajes), usted tiene un período de hasta 24 horas para reportar posibles errores. Pasadas las 24 horas desde que yo le envío la licencia supondré que todo funciona perfectamente y, cualquier cosa adicional será tratada como una cotización independiente.
  4. Si quiere contratar una licencia primero pruebe el plugin gratuito, ya que no hago reembolsos. Pruebe que funcione para usted y que funcione en todos los lugares donde lo necesite. Donde sea que el plugin funcione sin licencia, funcionará con licencia; pero la licencia no hará que el plugin funcione en lugares donde antes no lo hacía.
  5. La licencia es para uso personal y no se puede compartir. Se puede usar de manera ilimitada en computadoras ilimitadas o clientes ilimitados, siempre y cuando los clientes o dispositivos pertenezcan a la misma persona que contrató la licencia. En caso de que yo note que la licencia ha sido compartida, la misma será revocada sin importar el monto o tiempo.
  6. El contrato de una licencia no incluye soporte técnico gratuito. Le recomiendo probar todo con el plugin gratuito y si cree que funciona para lo que necesita, entonces puede contratar una licencia (si necesita ayuda o soporte envíeme un mensaje en https://parzibyte.me/#contacto)
  7. Una vez enviada la licencia, no hay devoluciones por ningún motivo, ya que aunque yo devuelva el pago, no se puede devolver la licencia al ser un bien digital.

Conclusión

En resumen, simplemente descarga el archivo de PDFtoPrinter.exe y el plugin, coloca ambos archivos en el mismo directorio y ejecuta el plugin, ya sea al iniciar Windows o manualmente.

En mi blog he escrito sobre cómo imprimir PDF usando este plugin. Puedes revisar los ejemplos en la siguiente categoría: Plugin PDF.

Con los ejemplos y la API es más que suficiente para comprender el funcionamiento, pero igualmente te dejo un vídeo en YouTube:

Por cierto, también tengo otro plugin para imprimir a impresoras térmicas POS.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

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.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

    • Invocar al plugin 2 veces, esperando a que la primera petición se resuelva antes de hacer la segunda

  • Me interesa adquirir el plugin y poder hacerle modificaciones. Pero no puedo contactarte por tu pagina de contacto. Me marca un error a la hora de hacer el request. Tienes algun otro medio de contacto?

    • Hola. Acabo de probar mi página de contacto y funciona correctamente, si le marca un error de request, simplemente vuelva a intentarlo

    • Hola. He recibido el pago correctamente, recuerde que es importante indicar su correo en el concepto de pago, aunque también lo puede indicar por este medio justo como lo acaba de hacer.
      Gracias por su compra, ya le he respondido por privado.

  • hola. me interesa el plugin. quiero el mismo sin que aparesca la marca de agua de "Encuentra mas programas en parzibyts"

    • Como te habrás dado cuenta, al momento de imprimir aparece una “marca de agua” con contenido y posición aleatorios. El plugin es totalmente gratis, pero debes respetar esa marca de agua con mis créditos.

      Si quieres removerla, puedes contratar una licencia. El costo de la misma es de 100 MXN (pesos mexicanos) mensuales (un mes se toma como un período de 30 días).

      Te invito a probar el plugin gratuito, y si te funciona en los lugares que necesitas entonces puedes contratar una licencia por los meses que creas convenientes haciendo el pago en https://parzibyte.me/blog/pagos-venta-software/ indicando el concepto y tu correo.

      Igualmente luego de hacer el pago puedes contactarme en https://parzibyte.me/#contacto en caso de que olvides poner el concepto o no te haya contactado.

      No olvides que lo único que hace la licencia es remover la marca de agua.

  • necesito imprimir el ticket desde php, tu plugin se le puede pasar como parametro el nombre del archivo desde php y este lo busque en servidor de cpanel, porque ahi quedan los ticket como archivo. espero tu respuesta...gracias

    • la idea es que no sea manual que al terminar que realizar la venta se imprima el voucher en la impresora, o tu crees que me puedes ayudar ahi hablamos la parte economica.

      • Sí, puede imprimir automáticamente invocando al plugin con JavaScript una vez que haya terminado la venta

Entradas recientes

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

3 días hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

3 días hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

3 días hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

3 días hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

3 días hace

Solución: Apache – Server unable to read htaccess file

Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…

3 días hace

Esta web usa cookies.