从 PHP 打印到 POS 打印机
Posted
技术标签:
【中文标题】从 PHP 打印到 POS 打印机【英文标题】:Printing to POS printer from PHP 【发布时间】:2014-11-16 08:35:42 【问题描述】:我们正在寻找连接到运行 apache 的 POS 打印机进行打印。由于应用程序的设计和部署,打印应该从服务器完成(它应该检测订单并发送到不同的打印机和不同格式的打印......账单,厨房订单,等等......)。由于这个原因和其他原因(例如从 iPad 访问应用程序),我们放弃了 QZ-Print 小程序等选项,需要直接在服务器端打印。
我们查了很多,发现有一个叫php-printer的扩展,但是好像已经过时了,只能在WIndows下运行。
我们遵循以下代码:(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);
它可以工作,但这会发送纯文本,我们需要发送图像(徽标),并格式化更可爱的账单。我们尝试创建 PDF 并以相同的方式“发送”到打印机,但只是打印空白。
我找到了一个可以使用网络打印机的库(github 上的 escpos-php),但我们也需要使用 USB 打印机,以避免我们的客户更改硬件。
一些想法如何实现这一目标?
提前致谢。
【问题讨论】:
【参考方案1】:escpos-php 的作者在这里。
如果您的打印机确实支持 ESC/POS(大多数热敏收据打印机似乎使用它的某些子集),那么我认为驱动程序将适应您的用例:USB 或网络打印、徽标、某些格式。其中一些是最近添加的。
USB 打印
escpos-php 打印到文件指针。在 Linux 上,您可以使用 usblp
驱动程序将 USB 打印机显示为文件,然后只需 fopen()
它(USB receipt example、blog post about installing a USB printer on Linux)。
因此,在 USB 打印机上打印“Hello world”与在网络打印机上打印仅略有不同:
<?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();
或者,更像您当前成功使用的代码,您可以写入临时文件并复制它:
<?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);
因此,在您的 POS 系统中,您需要一个根据您的客户配置和首选目的地返回文件指针的函数。收据打印机响应很快,但如果您有几台 iPad 下订单,您应该使用文件锁 (flock()) 将操作包装到每台打印机,以避免与并发相关的问题。
另请注意,Windows 上的 USB 支持未经测试。
徽标和格式
一旦您弄清楚您打算如何与打印机对话,您就可以使用全套格式和图像命令。
可以像这样从 PNG 文件中打印徽标:
use Mike42\Escpos\EscposImage;
$logo = EscposImage::load("foo.png");
$printer -> graphics($logo);
对于格式化,README.md 和下面的示例应该可以帮助您入门。对于大多数收据,您只需要:
selectPrintMode()
更改字体大小。
setEmphasis()
切换粗体。
setJustification()
左对齐或居中一些文本或图像。
cut()
每张收据后。
我还建议您在当前使用的示例中绘制这样的框:
=========
| |
=========
您可以使用 IBM Code page 437 中的字符,这些字符设计用于绘制许多打印机支持的框 - 只需在输出中包含字符 0xB3 到 0xDA。它们并不完美,但看起来少了很多“文本”-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);
完整示例
以下示例是带有驱动程序的also now included。我认为它看起来像是一张相当典型的商店收据,在格式方面,可以很容易地适应您的厨房场景。
扫描输出:
生成它的PHP源代码:
<?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";
【讨论】:
抱歉这么晚才回复。我以为我回复你了。是的,我完成了使用你的库,并且像一个魅力一样工作。我只是有一些小问题,但我会在 github 页面上发布讨论。谢谢。 我可以在 RP3150 STAR 和 TSC TE244 打印机上使用 escpos 吗? 如果从 Web 托管的应用程序打印则不起作用。 @AlphaMale 远程托管的 Web 应用程序不知道客户端打印机,我建议您开始研究像 qz.io、云打印或支持硬件的打印机等解决方案。 对我来说它的印刷垃圾字符而不是徽标。我该怎么办?以上是关于从 PHP 打印到 POS 打印机的主要内容,如果未能解决你的问题,请参考以下文章
使用 JavaScript 通过 ESC/POS 将图像打印命令发送到以太网上的热敏打印机