You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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输出到控制台,确认内容没问题再连真实打印机。
  • 权限问题:Linux下要给Web服务器用户(比如www-data)加访问USB设备的权限,可以把用户加到lp组,或者用chmod调整设备权限。
  • 中文打印:如果要打中文,得确保打印机支持GBK/UTF-8,要是不支持,就用escpos-php的EscposImage把中文转成图片打印(这个库支持图片输出)。
  • 容错机制:代码里加了打印失败就回退到原PDF生成的逻辑,避免用户拿不到发票。

3. 测试步骤

  1. 先用FilePrintConnector测试,看输出的小票内容是否正确;
  2. 切换到对应系统的打印机连接器,测试实际打印;
  3. 如果出错,看var/log/pos_print.log里的日志排查问题。

内容的提问来源于stack exchange,提问作者Velu narasimman

火山引擎 最新活动