php printing kiosk

Impresión a impresora POS desde PHP



printing kiosk (1)

Estamos buscando imprimir en una impresora POS conectada donde se está ejecutando Apache. Debido al diseño de la aplicación y la implementación, la impresión debe realizarse desde el Servidor (debe detectar el pedido y enviarse a diferentes impresoras y diferentes formatos de impresión ... facturas, pedidos de cocina, etc.). Por esta razón y otras (como la aplicación de acceso desde un iPad, por ejemplo) descartamos opciones como el applet QZ-Print y necesitamos imprimir directamente desde el lado del servidor.

Buscamos mucho y encontramos que hay una extensión llamada php-printer pero parece estar desactualizada, y simplemente funciona bajo Windows.

Seguimos este código: ( http://mocopat.wordpress.com/2012/01/18/php-direct-printing-printer-dot-matrix-lx-300/ )

$tmpdir = sys_get_temp_dir(); # ambil direktori temporary untuk simpan file. $file = tempnam($tmpdir, ''ctk''); # nama file temporary yang akan dicetak $handle = fopen($file, ''w''); $condensed = Chr(27) . Chr(33) . Chr(4); $bold1 = Chr(27) . Chr(69); $bold0 = Chr(27) . Chr(70); $initialized = chr(27).chr(64); $condensed1 = chr(15); $condensed0 = chr(18); $corte = Chr(27) . Chr(109); $Data = $initialized; $Data .= $condensed1; $Data .= "==========================/n"; $Data .= "| ".$bold1."OFIDZ MAJEZTY".$bold0." |/n"; $Data .= "==========================/n"; $Data .= "Ofidz Majezty is here/n"; $Data .= "We Love PHP Indonesia/n"; $Data .= "We Love PHP Indonesia/n"; $Data .= "We Love PHP Indonesia/n"; $Data .= "We Love PHP Indonesia/n"; $Data .= "We Love PHP Indonesia/n"; $Data .= "--------------------------/n"; $Data .= $corte; fwrite($handle, $Data); fclose($handle); copy($file, "//localhost/KoTickets"); # Lakukan cetak unlink($file);

Y funciona, pero esto envía texto sin formato, y necesitamos enviar imagen (logotipo) y formatear una factura más linda. Intentamos crear un PDF y "enviar" a la impresora de la misma manera, pero solo imprime en blanco.

Encontré una biblioteca para trabajar con impresoras de red (escpos-php en github), pero también necesitamos trabajar con impresoras USB para evitar que nuestros clientes cambien el hardware.

Algunas ideas de cómo lograr esto?

Gracias por adelantado.


Autor de escpos-php aquí.

Si sus impresoras son compatibles con ESC / POS (la mayoría de las impresoras térmicas de recibos parecen usar algún subconjunto de la misma), entonces creo que el controlador se adaptará a su caso de uso: USB o impresión en red, logotipo, algún formato. Algunos de estos son adiciones bastante recientes.

Impresión USB

escpos-php imprime a un apuntador de archivo. En Linux, puede hacer que la impresora USB sea visible como un archivo usando el controlador usblp , y luego simplemente fopen() ( ejemplo de recibo USB , publicación de blog sobre la instalación de una impresora USB en Linux ).

Por lo tanto, imprimir "Hello world" en una impresora USB es ligeramente diferente a imprimir en una impresora en red:

<?php require __DIR__ . ''/vendor/autoload.php''; use Mike42/Escpos/PrintConnectors/FilePrintConnector; use Mike42/Escpos/Printer; $connector = new FilePrintConnector("/dev/usb/lp0"); $printer = new Printer($connector); $printer -> text("Hello World!/n"); $printer -> cut(); $printer -> close();

O, más como el código que está utilizando con éxito, puede escribir en un archivo temporal y copiarlo:

<?php require __DIR__ . ''/vendor/autoload.php''; use Mike42/Escpos/PrintConnectors/FilePrintConnector; use Mike42/Escpos/Printer; /* Open file */ $tmpdir = sys_get_temp_dir(); $file = tempnam($tmpdir, ''ctk''); /* Do some printing */ $connector = new FilePrintConnector($file); $printer = new Printer($connector); $printer -> text("Hello World!/n"); $printer -> cut(); $printer -> close(); /* Copy it over to the printer */ copy($file, "//localhost/KoTickets"); unlink($file);

Por lo tanto, en su sistema POS, necesitará una función que devuelva un puntero de archivo según la configuración de su cliente y el destino preferido. Las impresoras de recibos responden con bastante rapidez, pero si tiene algunos iPads haciendo pedidos, debe ajustar las operaciones a cada impresora con un bloqueo de archivo ( flock() ) para evitar problemas relacionados con la concurrencia.

También tenga en cuenta que la compatibilidad con USB en Windows no está probada.

Logo y Formato

Una vez que haya descubierto cómo planea hablar con la impresora, puede utilizar el conjunto completo de comandos de formato e imagen.

Un logotipo se puede imprimir desde un archivo PNG de la siguiente manera:

use Mike42/Escpos/EscposImage; $logo = EscposImage::load("foo.png"); $printer -> graphics($logo);

Y para formatear, el README.md y el ejemplo a continuación deberían comenzar. Para la mayoría de los recibos, solo necesita realmente:

  • selectPrintMode() para alterar los tamaños de fuente.
  • setEmphasis() para alternar en negrita.
  • setJustification() para alinear a la izquierda o centrar texto o imágenes.
  • cut() después de cada recibo.

También sugeriría que, en la actualidad, esté utilizando un ejemplo que dibuje cuadros como este:

========= | | =========

Puede utilizar los caracteres en la página 437 de IBM Code, diseñados para dibujar cuadros que son compatibles con muchas impresoras; solo incluya los caracteres 0xB3 a 0xDA en la salida. No son perfectos, pero parece mucho menos "texto" -y.

$box = "/xda".str_repeat("/xc4", 10)."/xbf/n"; $box .= "/xb3".str_repeat(" ", 10)."/xb3/n"; $box .= "/xc0".str_repeat("/xc4", 10)."/xd9/n"; $printer -> textRaw($box);

Ejemplo completo

El siguiente ejemplo también se incluye con el controlador. Creo que parece un recibo de tienda bastante típico, en cuanto a formato, y podría adaptarse fácilmente al escenario de su cocina.

Salida escaneada:

Código fuente PHP para generarlo:

<?php require __DIR__ . ''/vendor/autoload.php''; use Mike42/Escpos/Printer; use Mike42/Escpos/EscposImage; use Mike42/Escpos/PrintConnectors/FilePrintConnector; /* Open the printer; this will change depending on how it is connected */ $connector = new FilePrintConnector("/dev/usb/lp0"); $printer = new Printer($connector); /* Information for the receipt */ $items = array( new item("Example item #1", "4.00"), new item("Another thing", "3.50"), new item("Something else", "1.00"), new item("A final item", "4.45"), ); $subtotal = new item(''Subtotal'', ''12.95''); $tax = new item(''A local tax'', ''1.30''); $total = new item(''Total'', ''14.25'', true); /* Date is kept the same for testing */ // $date = date(''l jS /of F Y h:i:s A''); $date = "Monday 6th of April 2015 02:56:25 PM"; /* Start the printer */ $logo = EscposImage::load("resources/escpos-php.png", false); $printer = new Printer($connector); /* Print top logo */ $printer -> setJustification(Printer::JUSTIFY_CENTER); $printer -> graphics($logo); /* Name of shop */ $printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH); $printer -> text("ExampleMart Ltd./n"); $printer -> selectPrintMode(); $printer -> text("Shop No. 42./n"); $printer -> feed(); /* Title of receipt */ $printer -> setEmphasis(true); $printer -> text("SALES INVOICE/n"); $printer -> setEmphasis(false); /* Items */ $printer -> setJustification(Printer::JUSTIFY_LEFT); $printer -> setEmphasis(true); $printer -> text(new item('''', ''$'')); $printer -> setEmphasis(false); foreach ($items as $item) { $printer -> text($item); } $printer -> setEmphasis(true); $printer -> text($subtotal); $printer -> setEmphasis(false); $printer -> feed(); /* Tax and total */ $printer -> text($tax); $printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH); $printer -> text($total); $printer -> selectPrintMode(); /* Footer */ $printer -> feed(2); $printer -> setJustification(Printer::JUSTIFY_CENTER); $printer -> text("Thank you for shopping at ExampleMart/n"); $printer -> text("For trading hours, please visit example.com/n"); $printer -> feed(2); $printer -> text($date . "/n"); /* Cut the receipt and open the cash drawer */ $printer -> cut(); $printer -> pulse(); $printer -> close(); /* A wrapper to do organise item names & prices into columns */ class item { private $name; private $price; private $dollarSign; public function __construct($name = '''', $price = '''', $dollarSign = false) { $this -> name = $name; $this -> price = $price; $this -> dollarSign = $dollarSign; } public function __toString() { $rightCols = 10; $leftCols = 38; if ($this -> dollarSign) { $leftCols = $leftCols / 2 - $rightCols / 2; } $left = str_pad($this -> name, $leftCols) ; $sign = ($this -> dollarSign ? ''$ '' : ''''); $right = str_pad($sign . $this -> price, $rightCols, '' '', STR_PAD_LEFT); return "$left$right/n"; } }