Plugin ESC POS v3

Imprimir en impresora térmica con Java

En este post vamos a ver cómo comunicar Java con una impresora térmica para imprimir imágenes, códigos QR, códigos de barra, texto, texto con acentos y darle estilo a los tickets desde ese lenguaje de programación.

Al final podrás usar NetBeans, IntelliJ IDEA, VSCode o cualquier editor en donde programes en Java para imprimir tickets en una impresora térmica.

Con el código mostrado aquí vas a ser capaz de imprimir recibos en una impresora térmica con Java ya sea desde la terminal, con Swing, en SpringBoot o cualquier cosa que programes con Java.

Prueba el nuevo diseñador

En estos días he creado un nuevo diseñador web para impresoras térmicas. El diseñador te guiará en el proceso de instalar tu impresora, compartirla e instalar lo necesario para imprimir tus diseños. Pruébalo en:

https://parzibyte.me/apps/ticket-designer/#/first-steps

Una vez que tengas tus diseños vas a poder imprimirlos desde cualquier lenguaje de programación, incluyendo Java.

Imprimir en impresora térmica con Java

Ticket impreso desde Java usando NetBeans – Comunicar impresora térmica con Java

Ahora sí vamos a lo que vinimos: la impresión de un ticket con Java. Comenzamos creando la lista de operaciones. En el siguiente ejemplo estamos iniciando la impresora, escribiendo un hola mundo, avanzando el papel 2 líneas e imprimiendo una imagen de internet.

// Lista completa: https://parzibyte.me/http-esc-pos-desktop-docs/es/
ArrayList<OperacionHttpEscPos> operaciones = new ArrayList<>();
operaciones.add(new OperacionHttpEscPos("Iniciar", new Object[]{}));
operaciones.add(new OperacionHttpEscPos("EscribirTexto", new Object[]{"Hola\nMundo\n"}));
operaciones.add(new OperacionHttpEscPos("Feed", new Object[]{2}));
operaciones.add(new OperacionHttpEscPos("DescargarImagenDeInternetEImprimir", new Object[]{"https://github.com/parzibyte.png", 380, 0, true}));

Debemos crear un ArrayList de tipo OperacionHttpEscPos y luego invocar a operaciones.add(new OperacionHttpEscPos("NombreDeLaOperacion", new Object[]{/*Argumentos*/}));

Puedes invocar a add cuantas veces sea necesario para agregar todas las operaciones con las que vas a diseñar tu ticket. La lista completa de operaciones está en la documentación.

Por ejemplo, la operación que permite descargar una imagen de internet para imprimirla recibe, en orden: la URL de la imagen, el ancho máximo, el algoritmo y una bandera indicando si se debería aplicar dithering. Por ello es que la definimos así:

operaciones.add(new OperacionHttpEscPos("DescargarImagenDeInternetEImprimir", new Object[]{"https://github.com/parzibyte.png", 380, 0, true}));

Una vez que tienes tu lista de operaciones definida, procedemos a crear la carga útil que se va a enviar. Aquí indicamos el nombre de la impresora:

String nombreImpresora = "Termica";
String serial = "";
ImpresionConNombre impresionConNombre = new ImpresionConNombre(operaciones, nombreImpresora, serial);

Ya tenemos el objeto creado, ahora solo falta codificarlo y enviarlo a la API HTTP local del plugin:

String postEndpoint = "http://localhost:8000/imprimir";
try {
    String inputJson = JSON.std.asString(impresionConNombre);
    var request = HttpRequest
            .newBuilder()
            .uri(URI.create(postEndpoint))
            .POST(HttpRequest.BodyPublishers.ofString(inputJson))
            .build();
    var client = HttpClient.newHttpClient();
    var respuestaHttp = client.send(request, HttpResponse.BodyHandlers.ofString());

    if (respuestaHttp.statusCode() != 200) {
        throw new Exception("código de respuesta distinto a 200. Verifique que el plugin se está ejecutando");
    }

    RespuestaHttpEscPos respuesta = JSON.std.beanFrom(RespuestaHttpEscPos.class, respuestaHttp.body());
    if (respuesta.isOk()) {
        System.out.println("Impreso correctamente");
    } else {
        System.out.println("Petición correcta, pero error en el plugin: " + respuesta.getMessage() + " . Documentación: https://parzibyte.me/http-esc-pos-desktop-docs/es/");
    }

} catch (Exception e) {
    System.out.println(e);
}

Puede verse complicado al inicio, pero en realidad solo estamos consumiendo una API HTTP REST local con Java usando JSON. La API está documentada en el siguiente enlace y puedes usar cualquier lenguaje de programación para consumirla:

https://parzibyte.me/http-esc-pos-desktop-docs/es/

Sigue leyendo para revisar los detalles sobre las clases de Java.

Clases necesarias y dependencias

Vamos a necesitar algunas clases programadas por mí para la interacción con el plugin de impresión térmica (servidor HTTP a ESC POS) y comandos ESC POS. La primera indica las operaciones ESC POS que se pueden hacer:

public class OperacionHttpEscPos {

    public String nombre;
    public Object[] argumentos;

    public OperacionHttpEscPos(String nombre, Object[] argumentos) {
        this.nombre = nombre;
        this.argumentos = argumentos;
    }
}

La segunda clase es la que contiene la lista de operaciones y el nombre de la impresora. Más adelante vamos a codificar esta clase y enviarla a la API:

public class ImpresionConNombre {

    public ArrayList<OperacionHttpEscPos> operaciones;
    public String nombreImpresora;
    public String serial;

    public ImpresionConNombre(ArrayList<OperacionHttpEscPos> operaciones, String nombreImpresora, String serial) {
        this.operaciones = operaciones;
        this.nombreImpresora = nombreImpresora;
        this.serial = serial;
    }
}

Finalmente debemos manejar la respuesta al imprimir para saber si la impresión ESC POS fue exitosa:

public class RespuestaHttpEscPos {
    private String message;
    private boolean  ok;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean isOk() {
        return ok;
    }

    public void setOk(boolean ok) {
        this.ok = ok;
    }
    
}

Como Java es un lenguaje fuertemente tipado debemos definir correctamente todos los datos que se van a manejar, indicando claramente las propiedades de cada clase. En mi caso cada clase está en su respectivo archivo llamado ImpresionConNombre.java, OperacionHttpEscPos.java y RespuestaHttpEscPos.java.

Dependencias de Java

El servidor local que convierte peticiones HTTP con JSON a operaciones ESC POS para impresoras térmicas se comunica con JSON, así que necesitamos convertir nuestras clases a JSON.

No encontré alguna manera nativa, así que agregué la dependencia jackson-jr que sirve para convertir a JSON desde Java.

La inclusión depende de tu IDE y entorno, pero yo he usado Maven con NetBeans y solo ha sido cuestión de agregar la siguiente dependencia a mi archivo pom.xml:

<dependency>
    <groupId>com.fasterxml.jackson.jr</groupId>
    <artifactId>jackson-jr-objects</artifactId>
    <version>2.13.0</version>
</dependency>

Solo como referencia, mi archivo pom.xml completo se ve así:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>me.parzibyte</groupId>
    <artifactId>mavenproject1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.release>17</maven.compiler.release>
        <exec.mainClass>me.parzibyte.mavenproject1.Mavenproject1</exec.mainClass>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.jr</groupId>
            <artifactId>jackson-jr-objects</artifactId>
            <version>2.13.0</version>
        </dependency>
    </dependencies>
</project>

Configurar impresora y descargar servidor HTTP a ESC POS

Para que el código funcione necesitas el servidor local de la API ESC POS ejecutándose y que tu impresora esté compartida. Por favor, sigue los pasos que aparecen en la página previamente enlazada, ya que ahí está la API unificada.

La documentación completa está en: https://parzibyte.me/http-esc-pos-desktop-docs/es/

Vídeo de apoyo

Código completo

El código completo para comunicar Java con una impresora térmica es el siguiente, excluyendo las 3 clases que mencioné previamente:

package me.parzibyte.mavenproject1;

import com.fasterxml.jackson.jr.ob.JSON;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;

/**
 *
 * @author parzibyte
 */public class Mavenproject1 {

    public static void main(String[] args) {
// Lista completa: https://parzibyte.me/http-esc-pos-desktop-docs/es/
        ArrayList<OperacionHttpEscPos> operaciones = new ArrayList<>();
        operaciones.add(new OperacionHttpEscPos("Iniciar", new Object[]{}));
        operaciones.add(new OperacionHttpEscPos("EscribirTexto", new Object[]{"Hola\nMundo\n"}));
        operaciones.add(new OperacionHttpEscPos("Feed", new Object[]{2}));
        operaciones.add(new OperacionHttpEscPos("DescargarImagenDeInternetEImprimir", new Object[]{"https://github.com/parzibyte.png", 380, 0, true}));

        String nombreImpresora = "Termica";
        String serial = "";
        ImpresionConNombre impresionConNombre = new ImpresionConNombre(operaciones, nombreImpresora, serial);
        String postEndpoint = "http://localhost:8000/imprimir";
        try {
            String inputJson = JSON.std.asString(impresionConNombre);
            var request = HttpRequest
                    .newBuilder()
                    .uri(URI.create(postEndpoint))
                    .POST(HttpRequest.BodyPublishers.ofString(inputJson))
                    .build();
            var client = HttpClient.newHttpClient();
            var respuestaHttp = client.send(request, HttpResponse.BodyHandlers.ofString());

            if (respuestaHttp.statusCode() != 200) {
                throw new Exception("código de respuesta distinto a 200. Verifique que el plugin se está ejecutando");
            }

            RespuestaHttpEscPos respuesta = JSON.std.beanFrom(RespuestaHttpEscPos.class, respuestaHttp.body());
            if (respuesta.isOk()) {
                System.out.println("Impreso correctamente");
            } else {
                System.out.println("Petición correcta, pero error en el plugin: " + respuesta.getMessage() + " . Documentación: https://parzibyte.me/http-esc-pos-desktop-docs/es/");
            }

        } catch (Exception e) {
            System.out.println(e);
        }
        System.out.println(operaciones);
    }
}

Siguientes pasos

Ahora ya puedes enviar recibos a impresoras térmicas desde Java de una manera muy fácil.

En resumen debes importar las clases y agregar la dependencia de jackson-jr para después crear una instancia del conector e imprimir.

Y la documentación así como los detalles del plugin, incluyendo conectores y más métodos (que te animo y casi obligo a leer) están en: https://parzibyte.me/http-esc-pos-desktop-docs/es/

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

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.