Printing to Pos Printer from PHP

Printing to POS printer from PHP

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:

Example formatted receipt including logo

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";
}
}

PHP Printing - How do I print directly from PHP on local server printer?

The source is commented and tells you the following.

From https://github.com/mike42/escpos-php/blob/master/example/interface/windows-usb.php:

/**
* Install the printer using USB printing support, and the "Generic / Text Only" driver,
* then share it (you can use a firewall so that it can only be seen locally).
*
* Use a WindowsPrintConnector with the share name to print.
*
* Troubleshooting: Fire up a command prompt, and ensure that (if your printer is shared as
* "Receipt Printer), the following commands work:
*
* echo "Hello World" > testfile
* copy testfile "\\%COMPUTERNAME%\Receipt Printer"
* del testfile
*/

And from https://github.com/mike42/escpos-php/blob/development/src/Mike42/Escpos/PrintConnectors/WindowsPrintConnector.php:

/**
* Connector for sending print jobs to
* - local ports on windows (COM1, LPT1, etc)
* - shared (SMB) printers from any platform (smb://server/foo)
* For USB printers or other ports, the trick is to share the printer with a
* generic text driver, then connect to the shared printer locally.
*/

See these articles on how to share a printer:

  • https://www.howtogeek.com/howto/windows-7/share-files-and-printers-in-windows-7-with-homegroup/
  • https://support.microsoft.com/en-us/windows/share-your-network-printer-c9a152b5-59f3-b6f3-c99f-f39e5bf664c3

Trying to connect thermal printer with pos php

I just found the solution actually I just have to replace:

$connector = new WindowsPrintConnector("My Printer Name Here");

and it is working fine.

printing from web(PHP) to local printer POS (point-of-sale) directly

As far as I understand you want a solution for server-side printing, right?

If it is a network-enabled printer that's connected to the server that serves the web page, you could use the lp Linux command. On Windows you can use the lpr command.

The file to print could be generated from the web page code with wkhtmltopdf or mpdf.

If it's not on the same network, you could set up a script on the printer network that checks an email address and sends the attachments from specific emails to the printer.

Web-based printing to a remote local thermal receipt printer

To be able access local USB deviced via the Webserver would be a huge security risk. Just think of a "evil" server that prints the whole wikipedia on any printer connected to a client, for example.

I don't think that there is a way to access any client-connected USB device with a simple web-based server software.
I would suggest either to

  1. get a receipt printer that shows up as a regular printer and just
    styling your receipts accordingly
  2. write a Thick Client instead or
  3. write a "print-agent" that regularly checks the server if there is any job for the locally connected receipt printer.

Either way, I do not think that, at this point, there is much use for PHP.

You could, of course, try tunneling USB via IP, but that would be quite a hassle to setup and maintain.



Related Topics



Leave a reply



Submit