# Guía de Impresión para Epson TM-U220 Esta guía documenta las mejores prácticas para generar impresiones legibles en impresoras Epson TM-U220 usando el sistema printerCentral. > **Nota:** Esta guía fue actualizada el 2025-11-26 basándose en pruebas reales con la impresora "Oficina Mami" (192.168.87.147). ## Especificaciones de la Impresora | Característica | Font A | Font B | |----------------|--------|--------| | Columnas (normal) | 33 | 40 | | Columnas (doble ancho) | 16 | 20 | | Descripción | Normal | Condensada | | Característica | Valor | |----------------|-------| | Ancho de papel | 57.5mm, 69.5mm, o 76mm | | Tipo | Matricial de impacto | ## Caracteres por Línea (Resumen Rápido) ``` Font A normal (1x1): 33 caracteres Font A doble ancho (2x1): 16 caracteres Font B normal (1x1): 40 caracteres Font B doble ancho (2x1): 20 caracteres ``` **Nota:** El doble alto (1x2) NO afecta la cantidad de caracteres horizontales. ## Caracteres Soportados ### ✅ FUNCIONAN (todos probados) **ASCII Básico:** ``` = - , : . ; " ' [ ] { } ( ) / | \ * # @ $ % & ^ ~ ` _ + < > A-Z a-z 0-9 espacio ``` **Box Drawing (para tablas):** ``` Líneas simples: ─ │ ┌ ┐ └ ┘ Líneas dobles: ═ ║ ╔ ╗ ╚ ╝ ``` **Bloques (para gráficos ASCII):** ``` Sólido: █ Medios: ▀ ▄ Sombras: ░ ▒ ▓ ``` **Símbolos:** ``` Círculos: ● ○ ◘ Flechas: ► ◄ ▲ ▼ Cartas: ♠ ♣ ♥ ♦ ``` **Latino Extendido:** ``` Español: ñ á é í ó ú ¿ ¡ Otros: ° ± ``` ### ❌ NO PROBADOS/EVITAR ``` Emojis: cualquiera Caracteres asiáticos Símbolos muy especiales: → ← ↑ ↓ ★ ``` ## Operaciones Soportadas ### Comandos que FUNCIONAN | Operación | Parámetros | Ejemplo | |-----------|------------|---------| | `text` | `value` | `{ "op": "text", "value": "Hola" }` | | `textAlign` | `align`: left, center, right | `{ "op": "textAlign", "align": "center" }` | | `textFont` | `font`: font_a, font_b | `{ "op": "textFont", "font": "font_a" }` | | `textSize` | `width`: 1-2, `height`: 1-2 | `{ "op": "textSize", "width": 2, "height": 1 }` | | `textStyle` | `em`, `ul` (booleans) | `{ "op": "textStyle", "em": true, "ul": true }` | | `textDouble` | `dw`, `dh` (booleans) | `{ "op": "textDouble", "dw": true }` | | `textRotate` | `rotate`: true/false | `{ "op": "textRotate", "rotate": true }` | | `textLineSpace` | `linespc`: número | `{ "op": "textLineSpace", "linespc": 50 }` | | `feedLine` | `line`: número | `{ "op": "feedLine", "line": 2 }` | | `feedUnit` | `unit`: número | `{ "op": "feedUnit", "unit": 50 }` | | `feed` | (ninguno) | `{ "op": "feed" }` | | `cut` | (ninguno, sin type) | `{ "op": "cut" }` | ### Comandos que NO FUNCIONAN | Operación | Motivo | |-----------|--------| | `textPosition` | No soportado en TM-U220 | | `textVPosition` | No soportado en TM-U220 | | `textSmooth` | Sin efecto (es para térmicas) | | `textLang` | Sin efecto | | `textStyle.reverse` | No soportado | | `textStyle.color` | Solo color_1 (negro) funciona | | `textFont` font_c/d/e | No existen en TM-U220 | | `textSize` > 2 | Se trata como 2 | | `cut` con `type` | Genera SchemaError | | `barcode` | No soportado (matricial) | | `qrcode` | No soportado (matricial) | | `imageRaw` | No soportado (matricial) | ## Estructura Recomendada de un Ticket ### Header (Centrado, Destacado) ```json { "op": "textAlign", "align": "center" }, { "op": "textSize", "width": 2, "height": 2 }, { "op": "textStyle", "em": true }, { "op": "text", "value": "TITULO" }, { "op": "textStyle", "em": false }, { "op": "textSize", "width": 1, "height": 1 }, { "op": "feedLine", "line": 2 } ``` **Importante:** Con doble ancho solo caben 16 caracteres en Font A. ### Separadores Usar 33 caracteres `=` para Font A (o 40 para Font B): ```json { "op": "text", "value": "=================================" }, { "op": "feedLine", "line": 1 } ``` ### Títulos de Sección ```json { "op": "textStyle", "em": true, "ul": true }, { "op": "text", "value": "NOMBRE SECCION" }, { "op": "textStyle", "em": false, "ul": false }, { "op": "feedLine", "line": 1 } ``` ### Items de Lista ```json { "op": "text", "value": "[ ] Item uno" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "[ ] Item dos" }, { "op": "feedLine", "line": 1 } ``` ### Footer y Corte ```json { "op": "textAlign", "align": "center" }, { "op": "text", "value": "Texto de pie" }, { "op": "feedLine", "line": 4 }, { "op": "cut" } ``` ## Ejemplo Completo ```json { "operations": [ { "op": "textAlign", "align": "center" }, { "op": "textSize", "width": 2, "height": 2 }, { "op": "textStyle", "em": true }, { "op": "text", "value": "MI TITULO" }, { "op": "textStyle", "em": false }, { "op": "textSize", "width": 1, "height": 1 }, { "op": "feedLine", "line": 2 }, { "op": "text", "value": "=================================" }, { "op": "feedLine", "line": 1 }, { "op": "textStyle", "em": true }, { "op": "text", "value": "SUBTITULO" }, { "op": "textStyle", "em": false }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "=================================" }, { "op": "feedLine", "line": 2 }, { "op": "textAlign", "align": "left" }, { "op": "textStyle", "em": true, "ul": true }, { "op": "text", "value": "SECCION 1" }, { "op": "textStyle", "em": false, "ul": false }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "[ ] Item A" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "[ ] Item B" }, { "op": "feedLine", "line": 2 }, { "op": "textAlign", "align": "center" }, { "op": "text", "value": "=================================" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "Pie de pagina" }, { "op": "feedLine", "line": 4 }, { "op": "cut" } ] } ``` ## Ejemplo con Box Drawing (Tabla) ```json { "operations": [ { "op": "textFont", "font": "font_a" }, { "op": "text", "value": "╔═══════════════╦═══════════════╗" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "║ PRODUCTO ║ PRECIO ║" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "╠═══════════════╬═══════════════╣" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "║ Cafe ║ $2.50 ║" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "║ Pan ║ $1.00 ║" }, { "op": "feedLine", "line": 1 }, { "op": "text", "value": "╚═══════════════╩═══════════════╝" }, { "op": "feedLine", "line": 4 }, { "op": "cut" } ] } ``` ## Endpoints de Impresión ### Imprimir Template Guardado ``` POST /api/print/template { "templateId": "template_xxx", "variables": { "nombre": "Juan" }, "printerId": "printer_xxx", // opcional "dryRun": false // true para preview } ``` ### Imprimir Operaciones Directas ``` POST /api/print/raw { "operations": [...], "variables": { "var1": "valor1" }, "printerId": "printer_xxx", // opcional "dryRun": false } ``` ## Variables en Templates Sintaxis: `{{nombre}}` o `{{nombre:label:default}}` ```json { "op": "text", "value": "Cliente: {{cliente}}" }, { "op": "text", "value": "Fecha: {{fecha:Fecha:2025-01-01}}" } ``` ## Errores Comunes 1. **Texto cortado**: Excediste 33 caracteres (Font A) o 40 (Font B) 2. **Todo pegado**: Falta `feedLine` entre elementos 3. **SchemaError en cut**: Usaste `cut` con parámetro `type` (no soportado) 4. **Header muy largo**: Con doble ancho solo caben 16 chars (Font A) 5. **Colores no funcionan**: Solo funciona color_1 (negro) 6. **Reverse no funciona**: No está soportado en TM-U220 ## Checklist Pre-Impresión - [ ] Ninguna línea excede 33 caracteres (16 si doble ancho) en Font A - [ ] Ninguna línea excede 40 caracteres (20 si doble ancho) en Font B - [ ] `feedLine` entre cada elemento para legibilidad - [ ] `feedLine: 4` antes del `cut` final - [ ] Header centrado con estilo bold - [ ] Usando sintaxis correcta: `textAlign`, `textStyle`, `feedLine` - [ ] `cut` sin parámetro `type` - [ ] No usando: textPosition, textVPosition, textSmooth, textLang