C# (C Sharp)

Imprimir en impresora térmica con C# y Visual Studio

En este artículo vamos a ver cómo comunicar C# con una impresora térmica usando Visual Studio, Mono o cualquier compilador que soporte C#. Es decir, no necesitas VS obligatoriamente siempre y cuando cuentes con el .NET framework necesario.

Imprimir ticket con C# y Visual Studio usando impresora térmica

Podrás usar C# (C sharp) para imprimir texto en una POS printer, alinear, colocar enfatizado, definir tus propios caracteres por si la impresora no lo soporta, imprimir acentos, texto según páginas de códigos y por supuesto podrás imprimir imágenes (locales, de internet o en base64), códigos QR, códigos de barras y todo lo necesario para crear tickets con C# en una thermal printer.

Para esto vamos a usar un conector que he creado con C# y un plugin gratuito. Esto funciona en Linux, Raspberry Pi, Windows y cualquier plataforma donde funcione mi plugin y C# se pueda compilar.

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 C#.

Imprimir ticket en impresora térmica con C sharp

Comencemos viendo un ejemplo para que veas lo sencillo que es comunicar C# con una thermal printer y crear tus facturas. Es un ejemplo muy simple que inicializa la impresora, imprime texto, avanza el papel e imprime una imagen de internet.

Diseñamos nuestro ticket agregando operaciones que puedes encontrar en la documentación oficial:

var operaciones = new List<OperacionHttpEscPos>();
// https://parzibyte.me/http-esc-pos-desktop-docs/es/esc-pos/iniciar.html
operaciones.Add(new OperacionHttpEscPos("Iniciar", new List<object> { }));
operaciones.Add(new OperacionHttpEscPos("EscribirTexto", new List<object> { "Hola\nMundo" }));
operaciones.Add(new OperacionHttpEscPos("Feed", new List<object> { 2 }));
// https://parzibyte.me/http-esc-pos-desktop-docs/es/esc-pos/imagen-de-internet.html
operaciones.Add(new OperacionHttpEscPos("DescargarImagenDeInternetEImprimir", new List<object> {
    "https://github.com/parzibyte.png",380,0,true,
}));

Puedes invocar a Add las veces que sea necesario, agregando una nueva operación ESC POS por cada invocación. Para saber lo que debes poner como nombre de operación y los argumentos visita la documentación oficial. Por ejemplo, veamos la documentación para descargar una imagen de internet e imprimirla.

Su nombre es DescargarImagenDeInternetEImprimir, sus argumentos son, en orden: la URL, el máximo ancho, el algoritmo (0 a 3) y un indicador para saber si se debería aplicar dithering, así que hay que colocar esos parámetros en new List<object>{} en el mismo orden.

La sintaxis es:

operaciones.Add(new OperacionHttpEscPos("NombreDeLaOperacion", new List<object> { /*Argumentos*/ }));

Ahora creamos la carga útil que lleva la lista de operaciones, el nombre de la impresora y un serial opcional:

//   https://parzibyte.me/http-esc-pos-desktop-docs/es/guia/instalar-compartir-impresora.html
var nombreImpresora = "Termica";
var serial = "";
ImpresionConNombrePluginV3 impresion = new ImpresionConNombrePluginV3(operaciones, nombreImpresora, serial);

Codificamos como JSON y lo enviamos a la ruta del servidor local para imprimir:

var serializado = JsonSerializer.Serialize(impresion);
try
{
    using (HttpClient client = new HttpClient())
    {
        StringContent content = new StringContent(serializado, Encoding.UTF8, "application/json");
        HttpResponseMessage response = await client.PostAsync("http://localhost:8000/imprimir", content);
        string respuestaComoJson = await response.Content.ReadAsStringAsync();
        RespuestaHttpEscPos respuestaHttpEscPos = JsonSerializer.Deserialize<RespuestaHttpEscPos>(respuestaComoJson);

        if (respuestaHttpEscPos.ok)
        {
            Console.WriteLine("Impreso correctamente");
        }
        else
        {
            Console.WriteLine("Petición realizada, pero error en el plugin: " + respuestaHttpEscPos.message);
        }
    }
}
catch (HttpRequestException e)
{
    Console.WriteLine("Error haciendo petición al plugin. Guía: https://parzibyte.me/http-esc-pos-desktop-docs/es/ el error es: " + e.ToString());
}

Así de fácil es imprimir un ticket con C#. Obviamente puedes invocar a cualquier operación, imprimir más imágenes, solo cortar el papel, solo abrir el cajón, imprimir un QR modificando la calidad, etcétera. Tú eres quien diseña los recibos.

Ahora sigue leyendo para ver cómo funciona el código y la lista de cosas que puedes hacer con tu impresora térmica usando este código que te muestro.

Configurando impresora y descargar servidor HTTP

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/

No tienes que instalar librerías adicionales, solo debes ejecutar el plugin, compartir tu impresora y definir las clases. Veamos entonces las clases necesarias para enviarle comandos ESC POS a una impresora térmica desde C#.

Clases para interactuar con una impresora térmica usando C#

Comencemos viendo las clases necesarias y el conector para el plugin. Primero la clase que representa una operación que podemos hacer en la impresora térmica, por ejemplo escribir texto, avanzar líneas, abrir el cajón, etcétera.

La lista completa de operaciones junto con sus argumentos está en: https://parzibyte.me/http-esc-pos-desktop-docs/es/

La acción puede o no tener argumentos y estos pueden ser de cualquier tipo.

public class OperacionHttpEscPos
{
    public string nombre { get; set; }
    public List<object> argumentos { get; set; }

    public OperacionHttpEscPos(string nombre, List<object> argumentos)
    {
        this.nombre = nombre;
        this.argumentos = argumentos;
    }
}

Luego vemos la clase que va a enviar las operaciones y además el nombre de la impresora térmica junto con una licencia (opcional) que será lo que se envía a la API HTTP a ESC POS:

public class ImpresionConNombrePluginV3
{
    public List<OperacionHttpEscPos> operaciones { get; set; }
    public string nombreImpresora { get; set; }
    public string serial { get; set; }

    public ImpresionConNombrePluginV3(List<OperacionHttpEscPos> operaciones, string nombreImpresora, string serial)
    {
        this.operaciones = operaciones;
        this.nombreImpresora = nombreImpresora;
        this.serial = serial;
    }
}

Y finalmente tenemos la clase que define la respuesta del plugin, ya que la API nos indicará si la impresión fue exitosa.

public class RespuestaHttpEscPos
{
    public string message { get; set; }

    public bool ok { get; set; }
}

Poniendo todo junto

Así que el código fuente completo para diseñar un recibo con C# desde Visual Studio y luego imprimirlo en una impresora térmica queda así:

using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

public class OperacionHttpEscPos
{
    public string nombre { get; set; }
    public List<object> argumentos { get; set; }

    public OperacionHttpEscPos(string nombre, List<object> argumentos)
    {
        this.nombre = nombre;
        this.argumentos = argumentos;
    }
}
public class ImpresionConNombrePluginV3
{
    public List<OperacionHttpEscPos> operaciones { get; set; }
    public string nombreImpresora { get; set; }
    public string serial { get; set; }

    public ImpresionConNombrePluginV3(List<OperacionHttpEscPos> operaciones, string nombreImpresora, string serial)
    {
        this.operaciones = operaciones;
        this.nombreImpresora = nombreImpresora;
        this.serial = serial;
    }
}

public class RespuestaHttpEscPos
{
    public string message { get; set; }

    public bool ok { get; set; }
}
class Program
{
    static async Task Main(string[] args)
    {

        //   https://parzibyte.me/http-esc-pos-desktop-docs/es/guia/instalar-compartir-impresora.html
        var nombreImpresora = "Termica";
        var operaciones = new List<OperacionHttpEscPos>();
        // https://parzibyte.me/http-esc-pos-desktop-docs/es/esc-pos/iniciar.html
        operaciones.Add(new OperacionHttpEscPos("Iniciar", new List<object> { }));
        operaciones.Add(new OperacionHttpEscPos("EscribirTexto", new List<object> { "Hola\nMundo" }));
        operaciones.Add(new OperacionHttpEscPos("Feed", new List<object> { 2 }));
        // https://parzibyte.me/http-esc-pos-desktop-docs/es/esc-pos/imagen-de-internet.html
        operaciones.Add(new OperacionHttpEscPos("DescargarImagenDeInternetEImprimir", new List<object> {
    "https://github.com/parzibyte.png",380,0,true,
}));
        var serial = "";
        ImpresionConNombrePluginV3 impresion = new ImpresionConNombrePluginV3(operaciones, nombreImpresora, serial);
        var serializado = JsonSerializer.Serialize(impresion);
        try
        {
            using (HttpClient client = new HttpClient())
            {
                StringContent content = new StringContent(serializado, Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.PostAsync("http://localhost:8000/imprimir", content);
                string respuestaComoJson = await response.Content.ReadAsStringAsync();
                RespuestaHttpEscPos respuestaHttpEscPos = JsonSerializer.Deserialize<RespuestaHttpEscPos>(respuestaComoJson);

                if (respuestaHttpEscPos.ok)
                {
                    Console.WriteLine("Impreso correctamente");
                }
                else
                {
                    Console.WriteLine("Petición realizada, pero error en el plugin: " + respuestaHttpEscPos.message);
                }
            }
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine("Error haciendo petición al plugin. Guía: https://parzibyte.me/http-esc-pos-desktop-docs/es/ el error es: " + e.ToString());
        }
    }
}

La lista de operaciones puede tener cualquier cantidad de elementos. Las operaciones ESC POS serán ejecutadas en el mismo orden que aparecen en la lista.

Documentación oficial: https://parzibyte.me/http-esc-pos-desktop-docs/es/

No olvides que también existe una versión para Android y que igualmente tengo otro plugin gratuito para imprimir un PDF silenciosamente desde cualquier lenguaje de programación.

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

  • Que tal excelente el funcionamiento del plugin, tengo una duda, como controlas el tamaño del ancho de papel de la impresora, en mi caso utilizo papel de 50mm y 80mm, de que manera controlas esa parte, muchas gracias.

    • Hola. Por el momento solo he trabajado con impresoras que tienen un único tamaño de papel, sería cuestión de que me hiciera llegar una impresora con esas características para poder probar

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.