☰
Dolibarr 内置的 escpos-php 收据打印驱动:ESC/POS 协议实现与 PHP 小票打印实战指南
2026/9/28 3:01:32 网站建设 项目流程
  • 企业应用
  • 后端

【免费下载链接】dolibarr

Dolibarr ERP CRM is a modern software package to manage your company or foundation's activity (contacts, suppliers, invoices, orders, stocks, agenda, accounting, ...). it's an open source Web application (written in PHP) designed for businesses of any sizes, foundations and freelancers.

项目地址:https://gitcode.com/gh_mirrors/do/dolibarr
点击查看免费下载

本文以 Dolibarr ERP/CRM 仓库内捆绑的 escpos-php 驱动 为核心,系统讲解其在 PHP 环境中生成并输出热敏收据小票(Receipt)的完整方案:从网络、串口、USB、SMB、CUPS 等连接方式的选择,到CapabilityProfile机型能力适配、条码/二维码/图片打印等全部公开 API,并深入 Dolibarr 的收银(Takepos)模块源码,展示如何复用该库实现真实的 POS 小票打印。读完本文,你将能够独立完成任意一款兼容 ESC/POS 协议的热敏打印机在 PHP / Dolibarr 环境下的接入与调试。

一、背景:什么是 ESC/POS,为什么需要它

ESC/POS 是爱普生(Epson)为热敏收据打印机制定的控制协议,目前已被绝大多数热敏小票打印机以不同程度支持。escpos-php 项目在 PHP 中实现了 ESC/POS 协议的一个子集,允许开发者通过统一 API 完成小票生成、基础排版、切纸、条码与二维码打印,从而为任意 PHP 应用(尤其是 Web 端 POS 收银系统)提供即插即用的小票打印能力。

在 Dolibarr 仓库中,该库被完整捆绑于 htdocs/includes/mike42/escpos-php 目录,并由收银模块 htdocs/takepos/class/dolreceiptprinter.class.php 直接继承使用——它通过require_once DOL_DOCUMENT_ROOT.'/includes/mike42/escpos-php/autoload.php'引入库,再让dolReceiptPrinter类extends Printer(见 dolreceiptprinter.class.php#L109-L121)。这说明该库不只是独立组件,更是 Dolibarr 小票打印能力的底层引擎。

二、兼容性:操作系统、接口与打印机型号

2.1 接口与操作系统组合

根据 README 兼容性章节,该驱动在以下 OS/接口组合上经过验证:

接口LinuxMacWindows
Ethernet(网络)是是是
USB是未测试是
USB 转串口是是是
串口 Serial是是是
并口 Parallel是未测试是
SMB 共享打印机是否是
CUPS 托管打印机是是否

从源码结构看,每种连接方式都对应一个独立的PrintConnector实现,位于 src/Mike42/Escpos/PrintConnectors,共提供FilePrintConnector、NetworkPrintConnector、WindowsPrintConnector、CupsPrintConnector、DummyPrintConnector、MultiplePrintConnector、UriPrintConnector、RawbtPrintConnector八种,与上表一一对应。

2.2 已验证的打印机型号

README 列出了一份长期维护的兼容打印机清单,涵盖了 Epson、Star、Bixolon、Xprinter、Zjiang、Gainscha、Rongta 等主流品牌(完整列表见 README),其中几个典型代表:

  • Epson 系列:TM-T20、TM-T20II、TM-T70、TM-T70II、TM-T81、TM-T82II、TM-T88II/III/IV/V、TM-U220、TM-U295、TM-U590/U590P 等;其中Epson FX-890 需要调用feedForm()释放纸张,TM-U295 需要调用release()释放单据(README#L89-L101)。
  • Star 系列:TSP100 ECO、TSP100III FuturePRNT、TSP-650、TUP-592、BSC10 等,Star 机型使用不同的控制命令,需搭配对应CapabilityProfile。
  • Xprinter 系列:XP-58、XP-80C、XP-90、XP-Q20011、XP-Q800、F-900、XP-365B 等。
  • Zjiang 系列:ZJ-5870、ZJ-5890(多厂商以 POS-5890 出售,ZJ-5890K/ZJ-5890T 亦可)、ZJ-8220、ZJ-8250 等。
  • 国产常见机型:Gainscha GP-5890x、gprinter GP-U80160I、Rongta RP58-U / RP80USE、Xeumior SM-8330、QPOS Q58M 等。

如果你使用的打印机不在清单中,通常也能兼容——ESC/POS 协议的普及度很高。README 建议将新的可用机型反馈给上游项目以扩充清单。

三、基本用法:从 Hello World 到真实打印

3.1 引入库文件

推荐通过 Composer 引入mike42/escpos-php包:

composer require mike42/escpos-php

在 Dolibarr 仓库中,该库已随源码捆绑,无需另行安装,直接使用其自带 autoload.php 即可:

require_once DOL_DOCUMENT_ROOT . '/includes/mike42/escpos-php/autoload.php';

3.2 运行环境要求

库的硬依赖很少(对应 composer.json 的require段):

  • PHP 7.0 及以上(composer.json 中平台配置锁定为php >=7.0.0);
  • json扩展:用于加载内置的打印机能力定义;
  • intl扩展:用于字符编码转换;
  • zlib扩展:用于解压捆绑资源(如码页数据)。

同时建议安装imagick或gd扩展以加速图片处理(composer.json 的suggest段注明:ext-imagick用于图片打印,是 PDF 打印与自定义字体所必需;ext-gd在存在时用于图片打印)。Dolibarr 管理页 htdocs/admin/receiptprinter.php 也特别注释了“escpos 库可能用到的gzdecode”这一依赖细节。

3.3 Hello World 小票

生成一张最小小票并输出到标准输出:

<?php /* Call this file 'hello-world.php' */ require __DIR__ . '/vendor/autoload.php'; use Mike42\Escpos\PrintConnectors\FilePrintConnector; use Mike42\Escpos\Printer; $connector = new FilePrintConnector("php://stdout"); $printer = new Printer($connector); $printer -> text("Hello World!\n"); $printer -> cut(); $printer -> close();

由于输出是原始字节流,可以用操作系统管道把结果转发给各种接口的打印机:

  • 以太网打印机(端口通常为 9100,配合nc):
    php hello-world.php | nc 10.x.x.x. 9100
  • Linux 本地 USB 打印机(usblp设备文件,含 USB 并口):
    php hello-world.php > /dev/usb/lp0
  • CUPS 托管打印机(经lp/lpr以 raw 模式提交):
    php hello-world.php > foo.txt lpr -o raw -H localhost -P printer foo.txt
  • Windows 网络打印机(先映射到文件再复制):
    php hello-world.php > foo.txt net use LPT1 \\server\printer copy foo.txt LPT1 del foo.txt

如果这一步无法出纸,应优先查阅操作系统与打印机文档,找到一条可用的系统打印命令后再回到 PHP 侧排查。

3.4 使用 PrintConnector 建立连接

PrintConnector是库与打印机之间的“管道”,负责把数据送达打印机。README 的推荐做法是:根据实际环境挑选最合适的 Connector,把它传入Printer构造器。

网络打印机示例(NetworkPrintConnector,接受 IP 与端口):

use Mike42\Escpos\PrintConnectors\NetworkPrintConnector; use Mike42\Escpos\Printer; $connector = new NetworkPrintConnector("10.x.x.x", 9100); $printer = new Printer($connector); try { // ... Print stuff } finally { $printer -> close(); }

串口打印机示例(FilePrintConnector,设备文件可以是任意可写文件,包括/dev/ttyS0):

use Mike42\Escpos\PrintConnectors\FilePrintConnector; use Mike42\Escpos\Printer; $connector = new FilePrintConnector("/dev/ttyS0"); $printer = new Printer($connector);

实用提示(README "Tips & examples"):

  • Linux设备文件常见位置:/dev/lp0(并口)、/dev/usb/lp1(USB)、/dev/ttyUSB0(USB 转串口)、/dev/ttyS0(串口);
  • Windows:并口为LPT1、串口为COM1。推荐用WindowsPrintConnector接入系统打印队列(USB、SMB 或 LPT),它通过队列提交打印作业而非直连设备,兼容性更稳。

3.5 使用 CapabilityProfile 适配打印机能力

不同品牌机型的命令集与码页差异很大。默认情况下驱动接受 UTF-8 输入,输出适合 Epson TM 系列的指令。当你试用新品牌打印机时,README 建议先用 "simple" 配置文件,让驱动避开高级特性(更简单的图片处理、纯 ASCII 文本),以降低踩坑概率:

use Mike42\Escpos\PrintConnectors\WindowsPrintConnector; use Mike42\Escpos\CapabilityProfile; $profile = CapabilityProfile::load("simple"); $connector = new WindowsPrintConnector("smb://computer/printer"); $printer = new Printer($connector, $profile);

Star 品牌打印机使用不同的指令集,示例:

use Mike42\Escpos\PrintConnectors\WindowsPrintConnector; use Mike42\Escpos\CapabilityProfile; $profile = CapabilityProfile::load("SP2000") $connector = new WindowsPrintConnector("smb://computer/printer"); $printer = new Printer($connector, $profile);

CapabilityProfile在源码中是“一台打印机的兼容性信息”容器(CapabilityProfile.php),内部记录支持的码页、特征开关等;Printer构造器未指定 profile 时会自动加载名为default的配置(Printer.php#L360-L369),该配置适用于 Epson 打印机。Dolibarr 的管理后台同样把打印机 profile 作为可配置参数,见 htdocs/admin/receiptprinter.php 中的printerprofileid字段。

四、可用 API 方法全解

以下按 README 的 "Available methods" 章节逐条展开,并结合 Printer.php 源码补充参数取值范围与底层指令。

4.1 构造与生命周期

  • __construct(PrintConnector $connector, CapabilityProfile $profile = null)创建打印对象。$connector为数据出口;$profile若省略则使用适合 Epson 打印机的default配置。构造时内部会建立EscposPrintBuffer缓冲并调用initialize()复位打印机(Printer.php#L360-L375)。
  • close():关闭连接。部分 Connector 只有调用close()后作业才会真正送达打印机(Printer.php#L496-L503)。
  • initialize():发送 ESC @ 复位指令,把所有格式恢复为默认值(Printer.php#L626-L632)。

4.2 条码打印

  • barcode($content, $type = Printer::BARCODE_CODE39)打印条码。源码会先按类型校验内容长度与字符集再发送指令(Printer.php#L390-L442)。支持的标准(是否可用取决于打印机):

    • BARCODE_UPCA(内容 11-12 位纯数字)
    • BARCODE_UPCE(6-8 或 11-12 位数字)
    • BARCODE_JAN13(12-13 位数字)
    • BARCODE_JAN8(7-8 位数字)
    • BARCODE_CODE39(1-255 字符,可含数字、大写字母与$%+-./及空格)
    • BARCODE_ITF(偶数位数字,至少 2 位)
    • BARCODE_CODABAR(1-255 字符,首尾需为 A-D 起始/结束符)

    注意:某些标准只能编码数字,传入非数字内容可能产生异常输出。此外源码中还有BARCODE_CODE93与BARCODE_CODE128两个常量,表明底层同样实现了这两种编码。

  • 配套设置方法:

    • setBarcodeHeight($height = 8):条码高度(点),范围 1-255(Printer.php#L788-L792)。
    • setBarcodeWidth($width = 3):条码条宽(点),范围 1-255,超过 6 通常无效果(Printer.php#L794-L804)。
    • setBarcodeTextPosition($position = Printer::BARCODE_TEXT_NONE):控制条码下方 HRI(人可读)字符是否显示,取BARCODE_TEXT_NONE/BARCODE_TEXT_ABOVE/BARCODE_TEXT_BELOW(Printer.php#L806-L817)。

4.3 图片打印

  • graphics(EscposImage $image, $size = Printer::IMG_DEFAULT)以较新的光栅图形指令打印图片。$size修饰符:

    • IMG_DEFAULT:保持原始尺寸
    • IMG_DOUBLE_WIDTH:水平加倍
    • IMG_DOUBLE_HEIGHT:垂直加倍

    最小示例:

    <?php $img = EscposImage::load("logo.png"); $printer -> graphics($img);

    源码中graphics()使用GS ( L封装发送光栅数据,并支持IMG_DOUBLE_WIDTH/IMG_DOUBLE_HEIGHT按位组合(Printer.php#L611-L623)。

  • bitImage(EscposImage $image, $size):使用较老的“位图”指令打印,适用于不支持graphics()的打印机(宽度不是 8 的倍数时右侧会补白,Printer.php#L456-L463)。

  • bitImageColumnFormat():列格式位图打印,作为更老机型的最后兜底方案(该功能在源码中标注为“尚未完全完成,可能产生不可预料的输出”,Printer.php#L476-L494)。

    图片加载由 EscposImage.php 及GdEscposImage/ImagickEscposImage/NativeEscposImage三个实现共同支撑,分别依赖 gd、imagick 或纯 PHP 原生解码。

4.4 切纸与走纸

  • cut($mode = Printer::CUT_FULL, $lines = 3):切纸。CUT_FULL全切 /CUT_PARTIAL半切(留一点连接),$lines为切纸前先走纸的行数(Printer.php#L505-L515)。
  • feed($lines = 1):走纸并打印换行(Printer.php#L518-L530)。
  • feedReverse($lines = 1):反向走纸 n 行,范围 1-255(Printer.php#L554-L558)。
  • feedForm():表单进纸。多数打印机仅在页模式下有效,而本驱动未实现页模式;但对 FX-890 等机型是释放纸张的必需调用(Printer.php#L532-L539)。
  • release():针对滑架(slip)打印机发送ESC q释放单据,TM-U295 等机型需要(Printer.php#L541-L547)。

4.5 二维码与 PDF417

  • qrCode($content, $ec = Printer::QR_ECLEVEL_L, $size = 3, $model = Printer::QR_MODEL_2)打印 QR 码:

    • $ec:纠错等级,QR_ECLEVEL_L(默认)/QR_ECLEVEL_M/QR_ECLEVEL_Q/QR_ECLEVEL_H,等级越高码越密;
    • $size:像素尺寸,必须为 1-16,默认 3;
    • $model:QR_MODEL_1、QR_MODEL_2(默认)、QR_MICRO(并非所有打印机支持)。

    源码中会对ec(0-3)、size(1-16)、model(1-3) 做严格校验,且当打印机的 CapabilityProfile 不支持 QR 时抛出异常(Printer.php#L696-L726)。

  • pdf417Code($content, $width = 3, $heightMultiplier = 3, $dataColumnCount = 0, $ec = 0.10, $options = Printer::PDF417_STANDARD)打印 PDF417 二维条码:

    • $width:模块宽度(点),默认 3;
    • $heightMultiplier:模块高度倍数,默认 3 倍宽;
    • $dataColumnCount:数据列数,0(默认)为自动计算;列数越小码越窄、可容纳更大像素;
    • $ec:纠错比例 0.01-4.00,默认 0.10(10%);
    • $options:PDF417_STANDARD(带起始/结束条)或PDF417_TRUNCATED(仅起始条)。

    源码校验范围:width 2-8、heightMultiplier 2-8、dataColumnCount 0-30、ec 0.01-4.00,且 profile 不支持时抛异常(Printer.php#L650-L678)。

4.6 文本与格式控制

  • text($str):向缓冲区追加文本(UTF-8)。文本应自带换行符,或之后调用feed()清空缓冲(Printer.php#L985-L995)。
  • textChinese($str):Zjiang(中江)打印机的中文专用通道——切换到双字节模式、用 UConverter 将 UTF-8 转成 GBK 发送(Printer.php#L998-L1011)。
  • textRaw($str):跳过字符编码解释,原样输出(Printer.php#L1013-L1024)。
  • selectPrintMode($mode = Printer::MODE_FONT_A):批量选择打印模式,多个MODE_*常量可用|组合:
    • MODE_FONT_A、MODE_FONT_B(字体 A/B)
    • MODE_EMPHASIZED(加粗强调)
    • MODE_DOUBLE_HEIGHT、MODE_DOUBLE_WIDTH(倍高/倍宽)
    • MODE_UNDERLINE(下划线) 默认值相当于执行了一次initialize()(Printer.php#L750-L771)。
  • setJustification($justification):对齐方式,JUSTIFY_LEFT(默认)/JUSTIFY_CENTER/JUSTIFY_RIGHT(Printer.php#L863-L872)。
  • setEmphasis($on = true)/setDoubleStrike($on = true):加粗强调 / 双重打印。
  • setFont($font = Printer::FONT_A):选字体,FONT_A/FONT_B/FONT_C(多数机器只有 A、B 两种)。
  • setTextSize($widthMultiplier, $heightMultiplier):按普通尺寸的倍数放大文本,两个参数范围均为 1-8(Printer.php#L948-L960)。
  • setUnderline($underline = Printer::UNDERLINE_SINGLE):下划线,可取布尔值或UNDERLINE_NONE/UNDERLINE_SINGLE/UNDERLINE_DOUBLE。
  • setReverseColors($on = true):黑白反显(白字黑底)。
  • setLineSpacing($height):行高(点);部分打印机允许用更小的行距让行重叠;传null恢复默认(Printer.php#L874-L891)。
  • setColor($color = Printer::COLOR_1):多色机型选色,COLOR_1(默认,通常黑)/COLOR_2(通常红或蓝)。
  • setPrintLeftMargin($margin):设置打印区左边界(点),initialize()复位(Printer.php#L893-L902)。
  • setPrintWidth($width = 512):设置打印区宽度(点),可用于制造右边界,initialize()复位(Printer.php#L904-L914)。
  • selectCharacterTable($table = 0):手动切换码页(配合textRaw()打印自动编码无法覆盖的特殊字符),码页是否可用由 CapabilityProfile 决定(Printer.php#L728-L748)。
  • setUpsideDown($on = true):文字倒置 180° 打印(Printer.php#L974-L982)。

4.7 外设控制

  • pulse($pin = 0, $on_ms = 120, $off_ms = 240):输出脉冲以打开钱箱(cash drawer)。$pin取 0 或 1,分别对应踢出接口的 pin 2 与 pin 5;默认参数即可打开爱普生钱箱。源码校验:on/off 时间 1-511ms,发送时以 2 为除数写入指令(Printer.php#L680-L694)。

五、Dolibarr 中的实战集成

5.1 类继承与连接器选择

Dolibarr 在收银模块中把打印能力封装为dolReceiptPrinter,它直接继承自Mike42\Escpos\Printer(dolreceiptprinter.class.php#L121),并在文件头部一次性引入五种连接器与图片类(dolreceiptprinter.class.php#L109-L116):

use Mike42\Escpos\PrintConnectors\FilePrintConnector; use Mike42\Escpos\PrintConnectors\NetworkPrintConnector; use Mike42\Escpos\PrintConnectors\WindowsPrintConnector; use Mike42\Escpos\PrintConnectors\CupsPrintConnector; use Mike42\Escpos\PrintConnectors\DummyPrintConnector; use Mike42\Escpos\Printer; use Mike42\Escpos\EscposImage;

这正是 README "Using a PrintConnector" 章节在真实项目中的落地:一个模块根据打印机配置(网络 IP、串口设备、Windows 队列名等)在运行时选择不同的 Connector。其中DummyPrintConnector被特别用于调试——Dolibarr 的测试打印逻辑会判断$connector instanceof DummyPrintConnector,若是则把打印内容写入日志,方便在无打印机环境下验证(dolreceiptprinter.class.php#L616-L618)。

5.2 测试页与真实小票模板

Dolibarr 管理页 htdocs/admin/receiptprinter.php 提供打印机的新增、编辑、删除与“发送测试页”功能(sendTestToPrinter($printerid))。测试页内容直接调用 README 中的 Hello World 模式:

$this->printer->text("Hello World!\n"); $this->printer->barcode($testStr); $this->printer->text("\n"); $this->printer->text("Most simple example\n"); $this->printer->cut();

(见 dolreceiptprinter.class.php#L605-L614)——一屏代码完整覆盖了文本、条码与切纸三个核心能力,可用于快速判断连接与驱动是否正常。

真实的销售小票则在此基础上大幅扩展:订单行逐行排版(商品引用、数量、含税单价右对齐)、按税率聚合税额、计算不含税/税额/含税合计等,均通过$this->printer->text()拼接输出(dolreceiptprinter.class.php#L802-L875),与 README 所述“真实小票包含对齐、加粗、条码”的用法一致。

六、开发、测试与贡献

该库以 MIT 协议发布,仓库鼓励开发者将修改回馈上游。以下是 README 给出的开发流程,全部可在捆绑目录内直接执行:

# 安装依赖 composer install # 运行单元测试(phpunit,带覆盖率文本输出) php vendor/bin/phpunit --coverage-text # PSR-2 编码规范检查 php vendor/bin/phpcs --standard=psr2 src/ -n # 重新生成 doxygen 开发者文档并检查告警 make -C doc clean && make -C doc

开发环境建议加载imagick、gd与Xdebug扩展。上游 CI 覆盖 PHP 7.0/7.1/7.2/7.3,更老版本的 PHP 与 HHVM 均不受支持。

七、注意事项与调试建议

  1. 先打通系统级打印,再上 PHP:README 反复强调,连接出问题时先用操作系统命令(nc、lpr、copy LPT1)确认打印机可用,再排查 PHP 侧。
  2. 新机型先降级:换品牌打印机时优先使用CapabilityProfile::load("simple"),避免高级指令(复杂图片、非 ASCII 文本)带来的兼容性坑。
  3. 切纸与走纸参数:cut()默认先走 3 行再切;部分机型需要feedForm()/release()才能释放纸张,务必按机型清单对照处理。
  4. 条码内容校验:barcode()在发送前会对内容长度与字符集做严格校验(Printer.php#L390-L442),报InvalidArgumentException时先检查内容是否符合所选码制。
  5. 收尾调用close():多数连接器在close()之前不会真正把作业送出,务必在finally块中调用,避免打印任务滞留。
  6. Dolibarr 场景:如果只需在 Dolibarr 内完成小票打印,优先使用 收银模块 与 管理配置页 的现成能力;如需深度定制,再直接基于本库 API 二次开发。

本文所涉源码均位于 htdocs/includes/mike42/escpos-php 目录,读者可结合 Printer.php、CapabilityProfile.php 与各 PrintConnector 实现 进一步研读底层指令细节。

  • 企业应用
  • 后端

【免费下载链接】dolibarr

Dolibarr ERP CRM is a modern software package to manage your company or foundation's activity (contacts, suppliers, invoices, orders, stocks, agenda, accounting, ...). it's an open source Web application (written in PHP) designed for businesses of any sizes, foundations and freelancers.

项目地址:https://gitcode.com/gh_mirrors/do/dolibarr
点击查看免费下载
上一篇:终极指南:使用Pyecharts在Python中创建专业级交互式数据可视化
下一篇:PSone.css高级技巧:自定义主题与响应式设计的完美结合

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询