Categorías: javascriptweb

Imprimir ticket en impresora térmica usando Javascript

Introducción

Actualización agosto 2019

¿Quieres imprimir con JavaScript sin usar el diálogo de impresión, con la posibilidad de cortar el papel y abrir el cajón de dinero? mira este post.

Recientemente escribí un tutorial sobre cómo imprimir un ticket en una impresora térmica usando PHP. Veamos entonces cómo podemos imprimir ticket en impresora térmica usando JavaScript.

Las complicaciones que tenemos al imprimir con PHP son:

  • Confusión de cómo usar la librería
  • Forzar a que el lenguaje del servidor sea PHP

Así que ahora decidí hacer una entrada para saber cómo imprimir un ticket en una impresora térmica sin usar PHP, sólo Javascript. El resultado será el siguiente:

Resultado final al Imprimir ticket en impresora térmica usando Javascript

Cuando terminemos, la interfaz se verá como aparece abajo. Puedes probarlo directamente haciendo click en Imprimir dentro de este enlace.

Lo único laborioso de esto es diseñar el ticket y adjuntar los productos.

Nota: lo he probado solamente con Chrome. Pero, independientemente del lugar, debemos quitar todos los márgenes y modificar un poco la escala para que el contenido ocupe el mayor espacio posible. Por ejemplo, así se ve sin ningún margen:

Vista previa al Imprimir ticket en impresora térmica usando Javascript

Imprimir ticket en impresora térmica usando Javascript

Diseñando el ticket

Vamos a comenzar definiendo un contenedor:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="style.css">
        <script src="script.js"></script>
    </head>
    <body>
        <div class="ticket">
        </div>
    </body>
</html>

Agregando una tabla

Vamos a tabular todo con una tabla, para que quede alineado:

<!DOCTYPE html>

<html>
    <head>
        <link rel="stylesheet" href="style.css">
        <script src="script.js"></script>
    </head>
    <body>
        <div class="ticket">
            <table>
                <thead>
                    <tr>
                        <th>CANT</th>
                        <th>PRODUCTO</th>
                        <th>$$</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>1.00</td>
                        <td>CHEETOS VERDES 80 G</td>
                        <td>$8.50</td>
                    </tr>
                    <tr>
                        <td>2.00</td>
                        <td>KINDER DELICE</td>
                        <td>$10.00</td>
                    </tr>
                    <tr>
                        <td>1.00</td>
                        <td>COCA COLA 600 ML</td>
                        <td>$10.00</td>
                    </tr>

                    <tr>
                        <td></td>
                        <td>TOTAL</td>
                        <td>$28.50</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

 

Estilos

Ahora falta definir nuestros estilos:

* {
    font-size: 12px;
    font-family: 'Times New Roman';
}

td,
th,
tr,
table {
    border-top: 1px solid black;
    border-collapse: collapse;
}

td.producto,
th.producto {
    width: 75px;
    max-width: 75px;
}

td.cantidad,
th.cantidad {
    width: 40px;
    max-width: 40px;
    word-break: break-all;
}

td.precio,
th.precio {
    width: 40px;
    max-width: 40px;
    word-break: break-all;
}

.centrado {
    text-align: center;
    align-content: center;
}

.ticket {
    width: 155px;
    max-width: 155px;
}

img {
    max-width: inherit;
    width: inherit;
}

Hay que notar que también definimos algunas clases para centrar texto y algunos estilos para una imagen.

Esto es porque le pondremos un logo más adelante. Por el momento nuestro ticket se ve así.

Logo y pie

Finalmente vamos a agregar un “Gracias por su compra” o algo que nosotros queramos, así como un logo.

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="style.css">
        <script src="script.js"></script>
    </head>
    <body>
        <div class="ticket">
            <img
                src="https://yt3.ggpht.com/-3BKTe8YFlbA/AAAAAAAAAAI/AAAAAAAAAAA/ad0jqQ4IkGE/s900-c-k-no-mo-rj-c0xffffff/photo.jpg"
                alt="Logotipo">
            <p class="centrado">TICKET DE VENTA<br>New New York<br>17/10/2017
                02:22 a.m.</p>
            <table>
                <thead>
                    <tr>
                        <th>CANT</th>
                        <th>PRODUCTO</th>
                        <th>$$</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>1.00</td>
                        <td>CHEETOS VERDES 80 G</td>
                        <td>$8.50</td>
                    </tr>
                    <tr>
                        <td>2.00</td>
                        <td>KINDER DELICE</td>
                        <td>$10.00</td>
                    </tr>
                    <tr>
                        <td>1.00</td>
                        <td>COCA COLA 600 ML</td>
                        <td>$10.00</td>
                    </tr>
                    <tr>
                        <td></td>
                        <td>TOTAL</td>
                        <td>$28.50</td>
                    </tr>
                </tbody>
            </table>
            <p class="centrado">¡GRACIAS POR SU COMPRA!<br>parzibyte.me</p>
        </div>
    </body>
</html>

Olvidé mencionar que tenemos que asignar las clases a las columnas y filas de las tablas, de la siguiente manera:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="style.css"> <script src="script.js"></script>
    </head>
    <body>
        <div class="ticket">
            <img
                src="https://yt3.ggpht.com/-3BKTe8YFlbA/AAAAAAAAAAI/AAAAAAAAAAA/ad0jqQ4IkGE/s900-c-k-no-mo-rj-c0xffffff/photo.jpg"
                alt="Logotipo">
            <p class="centrado">Parzibyte's blog
                <br>New New York
                <br>23/08/2017 08:22 a.m.</p>
            <table>
                <thead>
                    <tr>
                        <th class="cantidad">CANT</th>
                        <th class="producto">PRODUCTO</th>
                        <th class="precio">$$</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td class="cantidad">1.00</td>
                        <td class="producto">CHEETOS VERDES 80 G</td>
                        <td class="precio">$8.50</td>
                    </tr>
                    <tr>
                        <td class="cantidad">2.00</td>
                        <td class="producto">KINDER DELICE</td>
                        <td class="precio">$10.00</td>
                    </tr>
                    <tr>
                        <td class="cantidad">1.00</td>
                        <td class="producto">COCA COLA 600 ML</td>
                        <td class="precio">$10.00</td>
                    </tr>
                    <tr>
                        <td class="cantidad"></td>
                        <td class="producto">TOTAL</td>
                        <td class="precio">$28.50</td>
                    </tr>
                </tbody>
            </table>
            <p class="centrado">¡GRACIAS POR SU COMPRA!
                <br>parzibyte.me</p>
        </div>
    </body>
</html>

Ahora nuestro ticket luce mejor, y puedes verlo aquí.

Imprimiendo

Lo único que falta es agregar una forma de imprimirlo. Sólo tenemos que llamar a window.print desde JS. Si deseamos que se imprima instantáneamente, lo haremos así:

window.print();

Imprimiendo al hacer click

Lo que recomiendo es que mejor pongamos un botón que lo imprima, porque si lo imprimimos al instante puede que no se hayan cargado las imágenes, o cosas así. De todos modos la elección queda en nosotros.

Vamos a agregar un botón:

<button class="oculto-impresion" >

Y en el CSS vamos a ocultarlo, para que no salga al imprimir. Ya hice una entrada sobre esto aquí, por lo que no lo explicaré.

@media print {
    .oculto-impresion,
    .oculto-impresion * {
        display: none ;
    }
}

Finalmente definimos la función en Javascript:

function imprimir() {
  window.print();
}

Nuestro trabajo final se ve así.

Si hacemos click en el botón podemos ver que se imprime. Ahora simplemente tenemos que elegir la impresora y mandarlo.

Nota: puedes ocultar algunos elementos al imprimir, ya sea con CSS o con JavaScript y CSS.

Conclusión

Con esto podemos imprimir tickets y no sólo en la impresora térmica, también en cualquier otro dispositivo. Lo único de lo que debemos asegurarnos es de que nuestra impresora esté instalada correctamente.

Para dibujar los productos podemos hacerlo a mano, o con un framework como Vue, jQuery o AngularJS. Yo lo hice con javascript puro para hacerlo simple.

Si el ticket no funciona o no sale bien, podemos cambiar los pixeles y cualquier otra cosa. De esta manera podemos imprimir ticket en impresora térmica usando JavaScript

Recuerda: si quieres imprimir sin el diálogo de confirmación puede que quieras usar mi 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

  • veo que la opción de impresión window.print realiza una captura de pantalla, y es muy buena pero cuando son mas de 30 artículos queda a la mitad, o no se si yo lo estoy implementando mal.

  • Bro me sirvio de maravilla la idea para imprimir en el formato necesario en un hand held que viene con impresora térmica incluida, este tema me estaba matando pero con tu articulo logre integrar la idea a mi proyecto. Gracias!!!

  • Muy buen artículo, te agradezco porque explicas de manera simple cómo funciona. Quisiera saber cómo hago para que al dar en impimir() pueda guardar este archivo como pdf. Estoy en una mac y el cuadro de impresión de chrome dice "save as pdf" pero me sale por defecto un papel muy grande, quiero que salga un papel más pequeño para simular la generación del ticket real en pdf. Otra duda que tengo es cómo puedo saber cuantos píxeles de ancho son adecuados dependiendo del ancho del papel? es decir, explicaste que 8cm de ancho de papel, pero eso cuantos pixeles del CSS son? gracias

    • Funciona para la mayoría de impresoras térmicas, pero si es impresora de etiquetas, no, ya que estas últimas no utilizan ESC POS hasta donde tengo entendido.
      Saludos :)

  • disculpen mi ignorancia pero se puede imprimir desde un formato ya establecido en excel a la impresora ya instalada y pues si no es mucho pedir se podria mandar imprimir remotamente a una impresora termica portatil de 58 mm

    • Hola. Solo se puede con impresoras térmicas conectadas físicamente a la computadora; actualmente se puede solo en Windows en el navegador usando JavaScript.
      Saludos

  • Hola, que tal?

    He leido este post y me ha gustado mucho, me parecio tambien interesante, leí algunos comentarios ya que tengo un detalle y queria ver si alguno lo tenia, bueno el hecho es que al imprimirlo me imprime las letras muy pequeñas y deja mucho espacio en blanco, probe la solucion de cambiar los margenes, pero solo me funciono en chrome, para firefox no puedo hacer esta solucion, mi pregunta es ¿Hay alguna ottra manera de cambiar esos margenes de impresion?

    Ya probe tambien com @page{margin: 0; }

    Un saludo y gracias por el aporte :D

    De antemano gracias

  • saludos a todos, desde hace un tiempo vengo suministrando a algunos clientes un sistema hecho en php, javascript css utilizando como navegador el firefox y de impresoras las pos58 de varias marcas tengo varios drivers, si el cliente no los tiene yo se los instalo y bueno todo iba bien uso igual un boton en mi vista de impresion que llama a la caja de dialogo de la impresora claro por ello no es una impresion directa, un comando de javascript llama al windows paraimprimir windows printer lo cierto es que ahora nose si es que los navegadores estan interfiriendo con la tipografia de la letra pero me imprime simbolos raros antes imprimia exactamente lo que estaba en la pagina como una imagen claro connfiguranado e navegador con nada, nada, nada, nada en configurar pagina y con 0 en los margenes , entonces quiero saber si alguno de ustedes les paso y como solucionaron o si esto ustedes tien una idea de resolverlo, es algo en el juego de caracteres no me lo interpreta como antes nose si es el driver pero antes funcionaba bien nose si es el navegador yo tengo la sospecha de ello que los navegadores mas actualed de firefox dejaron atras a los drivers de la impresoras termicas en fin si uno de ustedes me pueden ayudar muchas gracias

  • recien veo este post y me parece interesante, pero el archivo script.js no lo encuntro cual seria?

  • Hola, quiero saber si hay alguna manera de seleccionar la impresora predeterminada del lado del cliente. Tengo un aplicativo web que me imprime directamente desde php, pero necesito implementarlo y que al cliente imprimir lo haga por la impresora predeterminada al presionar un botón desde mi aplicativo php

    • Hola, no se puede seleccionar una impresora por defecto ni imprimir sin confirmación con JavaScript, debido a la seguridad.
      Me parece que es posible hacerlo activando algunas banderas del navegador
      Otra idea que se me ocurre es programar un plugin que se ejecute en las computadoras de los clientes (algo así como un ejecutable, .exe, que imprima usando un lenguaje de servidor); de esta manera sería posible y fácil. Si estás interesado en que lo haga, puedes contactarme: https://parzibyte.me/blog/contacto/

  • Hola Parzibyte, recién descubro tu web y tiene contenido muy útil, te agradezco por el trabajo que dedicas a ello! Quería consultarte algo, quiero mandar una impresión a una impresora térmica bluetooth, estoy abierto a posibilidades con PHP y javascript ya que creo que solo con PHP no es posible. Tendrás alguna entrada con algún ejemplo que pueda usar? O alguna recomendación para mi? Gracias de antemano!

    • Hola, gracias por tus comentarios :)
      Sobre tu pregunta, no debería ser tan complejo mientras puedas imprimir desde la PC; es decir, si con Windows puedes, podrías imprimir desde JavaScript y otros lenguajes de programación.
      Comienza instalando los drivers y después de eso debería funcionar como cualquier otra impresora. Saludos :)

Entradas recientes

Creador de credenciales web – Aplicación gratuita

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

5 días 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.