从 PHP 打印到 POS 打印机

问题描述 投票:0回答:2

我们希望打印到运行 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打印机,以避免我们的客户更改硬件。

如何实现这一目标的一些想法?

提前致谢。

php printing kiosk
2个回答
64
投票

这里是escpos-php的作者。

如果您的打印机确实支持 ESC/POS(大多数热敏收据打印机似乎使用它的某些子集),那么我认为该驱动程序将适合您的用例:USB 或网络打印、徽标、某些格式。其中一些是最近添加的。

USB打印

escpos-php 打印到文件指针。在 Linux 上,您可以使用

usblp
驱动程序将 USB 打印机作为文件显示,然后只需
fopen()
USB 收据示例有关在 Linux 上安装 USB 打印机的博客文章)。

因此,在 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 代码页 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);

完整示例

下面的示例现在也包含在驱动程序中。我认为它看起来像一个相当典型的商店收据,格式明智,并且可以轻松适应您的厨房场景。

扫描输出:

Example formatted receipt including logo

生成它的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"; } }
    

-1
投票

在 Laravel 中使用 Mike42 的 Escpos 和 Brother 打印机进行打印的问题

我正在开发一个 Laravel 项目,其中使用 Mike42 ESC/POS 库向 Brother DCP-T510W 打印机发送打印命令。这是我的控制器中的 PHP 代码:

public function print() { try { $connector = new WindowsPrintConnector("Brother DCP-T510W"); $printer = new Printer($connector); $printer->text("Hello World"); $printer->cut(); $printer->close(); echo "Print job sent successfully.\n"; } catch (Exception $e) { echo "Couldn't print to this printer: " . $e->getMessage() . "\n"; } }
当我运行此程序时,会发生以下情况:

    我看到网络上出现“打印作业发送成功”的消息。
  1. 在 Brother DCP-T510W 打印机上,显示屏显示“正在接收数据”约 4-5 秒。
  2. 之后显示“100%正常01”,但打印机实际上并没有打印任何东西。
什么可能导致此问题?如何确保打印机执行打印作业?

如有任何帮助,我们将不胜感激!

© www.soinside.com 2019 - 2024. All rights reserved.