如何在Magento 1.9中集成escpos-php实现USB热敏发票打印?
搞定Magento 1.9用escpos-php打印USB热敏发票的方案
嘿,看你已经把escpos-php库放到Magento根目录,还自定义模块重写了发票模型,那接下来直接把原本生成C7 PDF的逻辑换成热敏打印就行,我给你整理好具体步骤和代码:
1. 修改自定义Invoice模型代码
打开/local/Receipt/Pos/Model/Invoice.php,把原本生成PDF的逻辑替换成下面的热敏打印代码——核心是引入escpos-php库,然后处理订单数据直接调用打印机:
<?php // 先引入escpos-php的自动加载文件,路径对应你放库的位置 require_once Mage::getBaseDir() . '/escpos-php/autoload.php'; use Mike42\Escpos\Printer; use Mike42\Escpos\PrintConnectors\FilePrintConnector; // 根据你的操作系统选对应的连接器: // Windows用这个:use Mike42\Escpos\PrintConnectors\WindowsPrintConnector; // Linux USB打印机用这个:use Mike42\Escpos\PrintConnectors\UsbPrintConnector; class Receipt_Pos_Model_Invoice extends Mage_Sales_Model_Order_Pdf_Invoice { // 重写原本生成PDF的getPdf方法,改成直接打印 public function getPdf($invoices = array()) { // 先复用原逻辑里的订单数据处理和门店环境切换 $this->_beforeGetPdf(); $this->_initRenderer('invoice'); foreach ($invoices as $invoice) { if ($invoice->getStoreId()) { Mage::app()->getLocale()->emulate($invoice->getStoreId()); Mage::app()->setCurrentStore($invoice->getStoreId()); } $order = $invoice->getOrder(); // 初始化打印机连接,先看你用的系统: // --- Windows示例:填你热敏打印机的名称(控制面板里能看到)--- // $connector = new WindowsPrintConnector("我的热敏打印机"); // --- Linux USB示例:填打印机的VendorID和ProductID(用lsusb命令查)--- // $connector = new UsbPrintConnector(0xXXXX, 0xXXXX); // --- 测试用:先输出到控制台看内容对不对 --- $connector = new FilePrintConnector("php://stdout"); try { $printer = new Printer($connector); // 打印店铺抬头 $printer->setJustification(Printer::JUSTIFY_CENTER); $printer->selectPrintMode(Printer::MODE_DOUBLE_WIDTH); $printer->text(Mage::getStoreConfig('general/store_information/name') . "\n"); $printer->selectPrintMode(); // 重置回普通字体 $printer->text(Mage::getStoreConfig('general/store_information/address') . "\n"); $printer->text("电话: " . Mage::getStoreConfig('general/store_information/phone') . "\n"); $printer->text("-----------------------------\n"); // 打印发票基本信息 $printer->setJustification(Printer::JUSTIFY_LEFT); $printer->text("发票编号: " . $invoice->getIncrementId() . "\n"); $printer->text("订单编号: " . $order->getIncrementId() . "\n"); $printer->text("下单时间: " . Mage::helper('core')->formatDate($order->getCreatedAtStoreDate(), 'medium', false) . "\n"); $printer->text("客户: " . $order->getCustomerName() . "\n"); $printer->text("-----------------------------\n"); // 打印商品明细 $printer->text("商品名称\t数量\t单价\t小计\n"); $printer->text("-----------------------------\n"); foreach ($invoice->getAllItems() as $item) { // 跳过子商品(比如捆绑商品里的子项) if ($item->getOrderItem()->getParentItem()) { continue; } $printer->text($item->getName() . "\t"); $printer->text($item->getQty() . "\t"); $printer->text(Mage::helper('core')->currency($item->getPrice()) . "\t"); $printer->text(Mage::helper('core')->currency($item->getRowTotal()) . "\n"); } $printer->text("-----------------------------\n"); // 打印合计信息 $printer->setJustification(Printer::JUSTIFY_RIGHT); $printer->text("小计: " . Mage::helper('core')->currency($invoice->getSubtotal()) . "\n"); $printer->text("税费: " . Mage::helper('core')->currency($invoice->getTaxAmount()) . "\n"); $printer->text("运费: " . Mage::helper('core')->currency($invoice->getShippingAmount()) . "\n"); $printer->selectPrintMode(Printer::MODE_BOLD); // 加粗打印总计 $printer->text("总计: " . Mage::helper('core')->currency($invoice->getGrandTotal()) . "\n"); $printer->selectPrintMode(); // 打印底部提示 $printer->setJustification(Printer::JUSTIFY_CENTER); $printer->text("\n感谢您的惠顾!\n"); $printer->text("-----------------------------\n"); // 切纸(如果你的打印机支持这个功能) $printer->cut(); $printer->close(); } catch (Exception $e) { // 打印失败就记录日志,然后 fallback 到原来的PDF生成逻辑 Mage::log('热敏打印出错: ' . $e->getMessage(), null, 'pos_print.log'); return parent::getPdf($invoices); } // 恢复门店环境 if ($invoice->getStoreId()) { Mage::app()->getLocale()->revert(); } } // 打印成功后给用户提示,然后跳回发票列表页 Mage::getSingleton('core/session')->addSuccess('发票已发送至热敏打印机'); $response = Mage::app()->getResponse(); $response->setRedirect(Mage::getUrl('sales/order/invoice')); $response->sendResponse(); exit; } }
2. 几个关键注意点要记牢
- 打印机连接要对应系统:
- Windows:用
WindowsPrintConnector,填打印机的实际名称(比如你在控制面板里看到的"热敏打印机"); - Linux:USB打印机先装驱动,用
UsbPrintConnector,需要用lsusb命令查打印机的VendorID和ProductID(比如0x04b8, 0x0e15); - 测试阶段先用
FilePrintConnector输出到控制台,确认内容没问题再连真实打印机。
- Windows:用
- 权限问题:Linux下要给Web服务器用户(比如www-data)加访问USB设备的权限,可以把用户加到
lp组,或者用chmod调整设备权限。 - 中文打印:如果要打中文,得确保打印机支持GBK/UTF-8,要是不支持,就用escpos-php的
EscposImage把中文转成图片打印(这个库支持图片输出)。 - 容错机制:代码里加了打印失败就回退到原PDF生成的逻辑,避免用户拿不到发票。
3. 测试步骤
- 先用
FilePrintConnector测试,看输出的小票内容是否正确; - 切换到对应系统的打印机连接器,测试实际打印;
- 如果出错,看
var/log/pos_print.log里的日志排查问题。
内容的提问来源于stack exchange,提问作者Velu narasimman




