Plugin impresoras Bluetooth Android

Imprimir ticket en impresora térmica bluetooth desde JavaScript con Android

El día de hoy vamos a hacer una cosa que varios me han pedido y que siempre he querido hacer: imprimir en una impresora térmica Bluetooth desde Android usando JavaScript.

Básicamente vamos a enviar un ticket a una thermal printer con Bluetooth desde el navegador web sin cuadros de diálogo ni cosas extrañas: tan solo usando un plugin gratuito desarrollado por mí y JavaScript puro.

Debido a que esto es hecho desde el navegador con JS luego puedes usarlo para imprimir en una impresora térmica Bluetooth desde Vue, React, Angular, TypeScript, etcétera: cualquier cosa que compile, use o traspile a JavaScript.

Demostración rápida

Si quieres probar antes de ver el código entonces sigue los siguientes pasos. Primero descarga, instala y dale los permisos al siguiente plugin:

Asegúrate de tener encendido el Bluetooth y de que le has dado todos los permisos al plugin, además de haber emparejado tu impresora térmica previamente.

Visita la siguiente página desde el dispositivo Android: https://parzibyte.github.io/imprimir-impresora-termica-bluetooth-javascript-android/

Coloca la MAC de tu impresora (por ejemplo FF:FF:FF:FF:FF:FF) y haz clic en Imprimir:

Página de demostración para imprimir en impresora térmica Bluetooth desde JavaScript

Debería imprimirse un ticket como el siguiente:

Imprimir en impresora térmica conectada por Bluetooth en Android desde JavaScript

En caso de que todo haya funcionado ya puedes seguir leyendo el post para ver cómo imprimir en una impresora térmica desde Android usando JavaScript.

Hola Impresora térmica Bluetooth desde JavaScript

Antes que nada descarga y ejecuta el plugin para Android:

Ahora debemos importar el conector, mismo que puedes descargar de: https://github.com/parzibyte/imprimir-impresora-termica-bluetooth-javascript-android/blob/main/ConectorEscposAndroid.js

Desde HTML vamos a importarlo:

<script src="./ConectorEscposAndroid.js" type="text/javascript"></script>
<script src="./main.js" type="text/javascript"></script>

En este caso main.js es el código que va a imprimir el ticket al presionar un botón. Cuando eso suceda se va a ejecutar el siguiente código:

const demostrarCapacidades = async (macImpresora, licencia) => {
    const conector = new ConectorEscposAndroid(licencia, URLPlugin);
    conector
        .Iniciar()
        .EstablecerAlineacion(ConectorEscposAndroid.ALINEACION_CENTRO)
        .DescargarImagenDeInternetEImprimir("http://assets.stickpng.com/thumbs/587e32259686194a55adab73.png", 0, 216)
        .Iniciar() // En mi impresora debo invocar a "Iniciar" después de imprimir una imagen
        .EstablecerAlineacion(ConectorEscposAndroid.ALINEACION_CENTRO)
        .Feed(1)
        .EscribirTexto("Parzibyte's blog\n")
        .EscribirTexto("Blog de un programador\n")
        .EscribirTexto("Teléfono: 123456798\n")
        .EscribirTexto("Fecha y hora: " + (new Intl.DateTimeFormat("es-MX").format(new Date())))
        .Feed(1)
        .EstablecerAlineacion(ConectorEscposAndroid.ALINEACION_IZQUIERDA)
        .EscribirTexto("____________________\n")
        .EscribirTexto("Venta de plugin para impresoras térmicas Bluetooth con Android (1 mes)\n")
        .EstablecerAlineacion(ConectorEscposAndroid.ALINEACION_DERECHA)
        .EscribirTexto("$7.00\n")
        .EscribirTexto("____________________\n")
        .EscribirTexto("TOTAL: $7.00\n")
        .EscribirTexto("____________________\n")
        .EstablecerAlineacion(ConectorEscposAndroid.ALINEACION_CENTRO)
        .EstablecerEnfatizado(true)
        .EstablecerTamañoFuente(1, 1)
        .EscribirTexto("¡Gracias por su compra!\n")
        .Feed(1)
        .ImprimirCodigoDeBarras("qr", "https://parzibyte.me/blog", ConectorEscposAndroid.TAMAÑO_IMAGEN_NORMAL, 160, 160)
        .Iniciar()
        .EstablecerAlineacion(ConectorEscposAndroid.ALINEACION_CENTRO)
        .Feed(1)
        .ImprimirCodigoDeBarras("code128", "parzibyte.me", ConectorEscposAndroid.TAMAÑO_IMAGEN_NORMAL, 320, 50)
        .Iniciar()
        .EstablecerAlineacion(ConectorEscposAndroid.ALINEACION_CENTRO)
        .Feed(1)
        .EstablecerTamañoFuente(1, 1)
        .EscribirTexto("parzibyte.me\n")
        .Feed(2)
        .Corte(1)
        .Pulso(48, 60, 120)

    try {
        const respuesta = await conector.imprimirEn(macImpresora);
        if (respuesta === true) {
            alert("Impreso correctamente");
        } else {
            alert("Error: " + respuesta);
        }
    } catch (e) {
        alert("Error imprimiendo: " + e.message);
    }
}

Primero creamos una nueva instancia de ConectorEscposAndroid pasándole la licencia y la URL del plugin. La licencia es un parámetro opcional pero lo estoy mostrando aquí para futuros ejemplos.

Luego podemos invocar a todos los métodos para armar nuestro ticket, ya sea para alinear, enfatizar, imprimir imágenes, etcétera (puedes ver la lista completa en el conector o en la documentación del plugin).

Una cosa es armar nuestro conector y llenarlo de operaciones y otra muy distinta es enviar esas operaciones invocando a imprimirEn, pasando la dirección MAC de la impresora.

Al invocar a imprimirEn se va a imprimir lo que hayamos definido en el conector, siempre y cuando el plugin se esté ejecutando en segundo plano. En este caso:

Imprimir en impresora térmica conectada por Bluetooth en Android desde JavaScript

 

¿Cómo funciona?

Al momento de escribir este post no hay mucho soporte para Bluetooth desde JavaScript, y el poco que existe es con BLE además de que es un lío pelear con las características y servicios.

Por ello es que decidí crear un plugin gratuito que permite ser invocado desde JavaScript (y otros lenguajes) para imprimir en una impresora térmica Bluetooth.

De este modo no necesitamos escapar del sandbox del navegador, solo necesitamos el plugin en ejecución.

Nota: recuerda que para invocar a localhost debes estar en un sitio con https.

Próximos pasos

Si quieres puedes ver el código fuente completo de la demostración: https://github.com/parzibyte/imprimir-impresora-termica-bluetooth-javascript-android

A partir del ejemplo de la demostración puedes imprimir desde cualquier lugar y en cualquier momento. Tal vez te interese ver la presentación del plugin o su documentación.

Si tú no eres de Android y usas impresoras USB tal vez te interese mi otro plugin.

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

  • Buen día, acabo de instalar el plugin tal cual indica el tutorial, pero no funciona me sale un mensaje de error: failed to fetch, el sitio en donde lo implemente es un sitio seguro con certificación en amazon y le ejecuto desde chrome, xfavor su ayuda

  • Hola... Existe alguna manera de imprimir archivo de base64 utilizando el plugin? Sería un reporte generado en Jasper .PDF

  • Hola, el plugin y su integración me funcionan de maravilla en una tablet Samsung Galaxy Tab A7, imprimiendo desde un sitio web. Sin embargo en una Galaxy Tab A, al abrir el plugin, se queda colgado mientras intenta buscar los dispositivos y nunca me muestra la lista. Tiene todo activado, internet, bluetooth, etc.
    Hay algún troubleshooting que pueda hacer para saber por qué no está cargando la lista de dispositivos en esa tablet?
    Ambas son modelos relativamente recientes y están actualizadas. Gracias de antemano.

    • Algo así pasaba con modelos con Android 12 pero ya fue arreglado en la última versión. Pruebe imprimir desde la web indicando la MAC

  • Hola buenas gracias por responder. Efectivamente el problema es ese, en tu pagina de prueba funciona pero en nuestro servidor de desarrollo no, usamos el localhost:8000 y la pagina desde la que intentamos accederlo es HTTPS. Por eso consulto que mas podemos probar ya que las condiciones estan dadas. Gracias por tu pronta respuesta. Saludos

    • ¿Cuál es la página desde la que intenta acceder y cuál es el puerto donde escucha el plugin? también recomiendo copiar el mensaje de error completo y pegarlo aquí

  • hola buenas, quisiera hacerte una consulta. Cuando pruebo el proyecto descargado de tu gitHub. Sin embargo al momento de probarlo en local me indica el error Failed to Fetch. el plugin esta corriendo en local por si acaso y la url es la especificada en el proyecto. Aguardo su consejo. Muchas gracias

  • Buenas tardes disculpa, en el movil no me aparece en el plug-in mi impresora ZEBRA IZM220, y cuando busco la pagina localhost:8000 me aparece "Ruta y o metodos no permitidos"

    • No debe abrir esa ruta en el navegador. Debe abrir el plugin, buscar su dispositivo y probar. Le recomiendo revisar minuciosamente el vídeo y post además de visitar la página de demostración

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

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…

2 semanas 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…

2 semanas 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…

2 semanas hace

Errores de Comlink y algunas soluciones

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

2 semanas 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…

2 semanas hace

Esta web usa cookies.