Introducción
Nota: te invito a leer cómo imprimir en impresora térmica usando Javascript, es un poco más fácil aunque tiene desventajas como no poder cortar el papel al gusto. Pero funciona sin tener que instalar librerías.
Las impresoras de tickets son muy populares y útiles en los establecimientos donde se necesita entregar un comprobante.
Puede que en alguna ocasión nos toque desarrollar un pequeño sistema en PHP y que tengamos que imprimir tickets.
Para ello es que escribo este tutorial; que al final nos dará un resultado parecido al siguiente:

Si quieres descargar un ejemplo rápido y funcional, mira el repositorio de GitHub. Solo tienes que descargar el código, cambiar el nombre de tu impresora y probar.
Requisitos
- Impresora instalada correctamente - Puedes ver cómo instalar una impresora genérica aquí
- PHP 5.3 o una versión superior - Puedes ver cómo instalar PHP 7 en otro post que hice
- Librería desarrollada por mike42 que podemos encontrar en GitHub aquí
Paso 1: Descargar librería
Actualización 2020: varios usuarios me dicen que no encuentran el autoload. Es cuestión de usar composer, pero si no quieres, puedes descargar el autoload y la carpeta src desde mi perfil de GitHub.
Vamos a ir al repositorio de GitHub y hacer clic en Download ZIP (también podemos clonar el repositorio si es que sabemos usar git).

Después, vamos a extraer ese archivo en una carpeta de nuestra elección.
Esta carpeta debe ser una carpeta que sea accesible desde nuestro entorno de desarrollo web. Si usamos XAMPP, la carpeta está en C:\xampp\htdocs.
Nos tiene que quedar algo así:

Paso 2: Eliminar archivos innecesarios
Entraremos a la carpeta y sólo dejaremos la carpeta src y el archivo autoload.php. Lo demás podemos eliminarlo:

Vamos a renombrar la carpeta a un nombre más fácil de recordar. En mi caso la llamaré “ticket”
Hasta el momento nuestro proyecto debe lucir así:

Paso 3: Hola mundo
Vamos a crear un archivo llamado index.php en donde está la carpeta que acabamos de renombrar, de manera que quede así:

Dentro del archivo vamos a escribir lo siguiente:
<?php
require __DIR__ . '/ticket/autoload.php'; //Nota: si renombraste la carpeta a algo diferente de "ticket" cambia el nombre en esta lÃnea
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
/*
Este ejemplo imprime un hola mundo en una impresora de tickets
en Windows.
La impresora debe estar instalada como genérica y debe estar
compartida
*/
/*
Conectamos con la impresora
*/
/*
Aquí, en lugar de "POS-58" (que es el nombre de mi impresora)
escribe el nombre de la tuya. Recuerda que debes compartirla
desde el panel de control
*/
$nombre_impresora = "POS-58";
$connector = new WindowsPrintConnector($nombre_impresora);
$printer = new Printer($connector);
/*
Imprimimos un mensaje. Podemos usar
el salto de lÃnea o llamar muchas
veces a $printer->text()
*/
$printer->text("Hola mundo\nParzibyte.me");
/*
Hacemos que el papel salga. Es como
dejar muchos saltos de línea sin escribir nada
*/
$printer->feed();
/*
Cortamos el papel. Si nuestra impresora
no tiene soporte para ello, no generará
ningún error
*/
$printer->cut();
/*
Por medio de la impresora mandamos un pulso.
Esto es útil cuando la tenemos conectada
por ejemplo a un cajón
*/
$printer->pulse();
/*
Para imprimir realmente, tenemos que "cerrar"
la conexión con la impresora. Recuerda incluir esto al final de todos los archivos
*/
$printer->close();
?>
Y al llamarla desde localhost/probarticket/ticket.php el resultado es el siguiente:

Pero no sólo podemos hacer eso, podemos hacer muchísimas cosas más.
En el repositorio oficial podemos encontrar miles de ejemplos, pero en este caso haré uno para imprimir un ticket de venta.
Ejemplo: Ticket de venta
<?php
require __DIR__ . '/ticket/autoload.php'; //Nota: si renombraste la carpeta a algo diferente de "ticket" cambia el nombre en esta lÃnea
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
/*
Este ejemplo imprime un
ticket de venta desde una impresora térmica
*/
/*
Una pequeña clase para
trabajar mejor con
los productos
Nota: esta clase no es requerida, puedes
imprimir usando puro texto de la forma
que tú quieras
*/
class Producto{
public function __construct($nombre, $precio, $cantidad){
$this->nombre = $nombre;
$this->precio = $precio;
$this->cantidad = $cantidad;
}
}
/*
Vamos a simular algunos productos. Estos
podemos recuperarlos desde $_POST o desde
cualquier entrada de datos. Yo los declararé
aquí mismo
*/
$productos = array(
new Producto("Papas fritas", 10, 1),
new Producto("Pringles", 22, 2),
/*
El nombre del siguiente producto es largo
para comprobar que la librería
bajará el texto por nosotros en caso de
que sea muy largo
*/
new Producto("Galletas saladas con un sabor muy salado y un precio excelente", 10, 1.5),
);
/*
Aquí, en lugar de "POS-58" (que es el nombre de mi impresora)
escribe el nombre de la tuya. Recuerda que debes compartirla
desde el panel de control
*/
$nombre_impresora = "POS-58";
$connector = new WindowsPrintConnector($nombre_impresora);
$printer = new Printer($connector);
/*
Vamos a imprimir un logotipo
opcional. Recuerda que esto
no funcionará en todas las
impresoras
Pequeña nota: Es recomendable que la imagen no sea
transparente (aunque sea png hay que quitar el canal alfa)
y que tenga una resolución baja. En mi caso
la imagen que uso es de 250 x 250
*/
# Vamos a alinear al centro lo próximo que imprimamos
$printer->setJustification(Printer::JUSTIFY_CENTER);
/*
Intentaremos cargar e imprimir
el logo
*/
try{
$logo = EscposImage::load("logo.png", false);
$printer->bitImage($logo);
}catch(Exception $e){/*No hacemos nada si hay error*/}
/*
Ahora vamos a imprimir un encabezado
*/
$printer->text("Yo voy en el encabezado" . "\n");
$printer->text("Otra linea" . "\n");
#La fecha también
$printer->text(date("Y-m-d H:i:s") . "\n");
/*
Ahora vamos a imprimir los
productos
*/
# Para mostrar el total
$total = 0;
foreach ($productos as $producto) {
$total += $producto->cantidad * $producto->precio;
/*Alinear a la izquierda para la cantidad y el nombre*/
$printer->setJustification(Printer::JUSTIFY_LEFT);
$printer->text($producto->cantidad . "x" . $producto->nombre . "\n");
/*Y a la derecha para el importe*/
$printer->setJustification(Printer::JUSTIFY_RIGHT);
$printer->text(' $' . $producto->precio . "\n");
}
/*
Terminamos de imprimir
los productos, ahora va el total
*/
$printer->text("--------\n");
$printer->text("TOTAL: $". $total ."\n");
/*
Podemos poner también un pie de página
*/
$printer->text("Muchas gracias por su compra\nparzibyte.me");
/*Alimentamos el papel 3 veces*/
$printer->feed(3);
/*
Cortamos el papel. Si nuestra impresora
no tiene soporte para ello, no generará
ningún error
*/
$printer->cut();
/*
Por medio de la impresora mandamos un pulso.
Esto es útil cuando la tenemos conectada
por ejemplo a un cajón
*/
$printer->pulse();
/*
Para imprimir realmente, tenemos que "cerrar"
la conexión con la impresora. Recuerda incluir esto al final de todos los archivos
*/
$printer->close();
?>

Ya después podemos hacer uso de number_format, poner el cambio, un mensaje dependiendo de la hora, etcétera.
Conclusión
En el repositorio oficial hay ejemplos para imprimir códigos qr, códigos de barras, y otras cosas más.
Recuerda, si quieres imprimir nativamente a la impresora de tickets, sin depender de PHP mira este post.
Si usas Laravel mira cómo integrar la librería en Laravel.