Author of escpos-php here.
If your printers do support ESC/POS (most thermal receipt printers seem to use some sub-set of it), then I think the driver will accommodate your use case: USB or network printing, logo, some formatting. Some of these are quite recent additions.
USB printing
escpos-php prints to a file pointer. On Linux, you can make the USB printer visible as a a file using the usblp
driver, and then just fopen()
it (USB receipt example, blog post about installing a USB printer on Linux).
So printing "Hello world" on a USB printer is only slightly different to printing to a networked printer:
<?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();
Or, more like the code you are currently using successfully, you could write to a temp file and copy it:
<?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);
So in your POS system, you would need a function which returns a file pointer based on your customer configuration and preferred destination. Receipt printers respond quite quickly, but if you have a few iPads making orders, you should wrap operations to each printer with a file lock (flock()) to avoid concurrency-related trouble.
Also note that USB support on Windows is un-tested.
Logo & Formatting
Once you have figured out how you plan to talk to the printer, you can use the full suite of formatting and image commands.
A logo can be printed from a PNG file like so:
use Mike42\Escpos\EscposImage;
$logo = EscposImage::load("foo.png");
$printer -> graphics($logo);
And for formatting, the README.md and the example below should get you started. For most receipts, you only really need:
selectPrintMode()
to alter font sizes.
setEmphasis()
to toggle bold.
setJustification()
to left-align or center some text or images.
cut()
after each receipt.
I would also suggest that where you are currently using an example that draws boxes like this:
=========
| |
=========
You could make use of the characters in IBM Code page 437 which are designed for drawing boxes that are supported by many printers- just include characters 0xB3 to 0xDA in the output. They aren't perfect, but it looks a lot less "text"-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);
Full example
The below example is also now included with the driver. I think it looks like a fairly typical store receipt, formatting-wise, and could be easily adapted to your kitchen scenario.
Scanned output:
PHP source code to generate it:
<?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";
}
}