ESC/POS指令开发
背景技术
随着科学技术的不断发展和人们生活水平的持续提高,商场、超市、餐饮店面等各 种消费场所都开始使用收银系统对消费者购买的商品进行结算,实现了自动化商业的管 理。由于收银系统可以提高收银、结算效率,避免计算错误,精简人手、节约人力资源,且能 够保留结算证据、实现有据可查,因此,收银系统在人们的日常生活中越来越普遍的被使 用。一般来说,收银系统包括收银机和打印机。而且,随着银行卡使用的不断普及,顾客在收 银系统结账时,经常会采用刷卡消费的方式。为此,由收银系统和P0S终端集成的P0S系统使 用的方式也越来越普及。
为了简化P0S系统的整体结构,一般来说,P0S系统中不再单独的设置一台物理打印机,而是采用支持标准ESC (Escape,转义字符)指令集的热敏打印模块集成在P0S终端内部,由P0S终端完成票据的打印工作。ESC指令集最早是EPSON公司自己制定的针式打印机的 标准化指令集,现在已成为嵌入式打印机控制语言上的工业标准,现在大多数P0S终端票据 打印都采用该指令集。其显著特征是:其中很大一部分指令都是以ESC控制符开始的一串代码。
P0S终端内部的打印模块中的ESC指令集对文字打印的大致处理过程是:首先,获 得二进制编码字符串和ESC指令的混合数据,其中,字符编码一般英文采用ASCI I编码,中文采用Gffi编码等其次,解析每个字符,从打印模块的内部字库中获得该字符的bitmap (位图)点阵接着,按照字符之间ESC排版指令和bitmap点阵进行输出图像的排版最后,调用打印机接口进行图像的输出。
连接方式
EscPos 为目前主流小票打印机都支持的一种打印机控制命令集, 而其很重要的一个特点是无需驱动支持。 有以下方式可以向一台打印机发送这种命令。
串口/并口连接:向串口(COM)/并口写入命令
USB连接的情况下,直接向 LPT1 这个设备写入命令。在windows下,外接设备被映射到系统中,其实也有其自己的路径, 不过这个路径和一般的文件路径不一样罢了, 如果从Linux的/dev/sda0 => /mnt/sda0 这样来理解可能会好理解点。那么使用CreateFile(设备路径), 获取一个缓冲区地址,然后往这个缓冲区写入数据,数据就会被发送到设备,以实现通讯
网线连接。一般的小票打印机都可以插网线,同时开放了9100这个端口, 可以通过socket建立连接,向这个端口发送数据,也同样可以和设备建立通讯连接
模板设计
小票打印机, 目前主要有这么几个宽度规格 58mm 70mm 80mm,常见的58mm和80mm为用得比较多, 对于模板的设计来说,其中的区别基本上只在于每行可以显示多少个字符。58mm的小票热敏纸,一行最大可以显示32个半角字符,而80mm的则可以显示48个半角字符。
由于小票的适用范围, 其实可以归结为以下几点:
小票可以看作是一行一行的字符拼接成完整的小票, 按照布局上来说, 那么就像是一个只有一栏的表格, 只要决定了每一行是什么样子, 整体的样子就有了
由于小票一般都不是很宽,那么一个字符或者一个字符串在当前行的某个具体位置并不重要,只需要 居左 居中 居右 三种位置属性即可,即使有, 横向的布局也应该是横向的填充布局
小票不需要很多很花的样式
。。。
基于以上几点, 将小票分为三个部分
头
体
尾
头的部分,主要显示标题、打印时间、单号等信息 体的部分,主要显示项目明细,从一个List里按顺序输出每行即可 尾的部分,一些其他内容,可以是文本,可以是链接
按照上面github的这个库里所说, 把内容类型分为 文本 条形码 二维码 和图片,黑白的情况下,图片并不是很有必要
常用ESC/POS指令整理表
命令编号 |
中文名 |
指令 |
参数 |
命令长度 |
参数大小范围 |
字符串 |
HEX格式 |
1 |
水平TAB定位 |
HT |
1 |
'\x09' |
9 |
||
2 |
打印并换行 |
LF |
1 |
'\x0A' |
0A |
||
3 |
打印并回归复始 |
FF |
1 |
'\x0C' |
0C |
||
4 |
打印并回车 |
CR |
1 |
'\x0D' |
0D |
||
5 |
页模式下取消打印数据 |
CAN |
1 |
'\x18' |
18 |
||
6 |
实时产生指定脉冲 |
DLE DC4 |
2 |
'\x10\x14' |
10 14 |
||
7 |
实时传送指定状态 |
DLE DC4 7 |
3 |
'\x10\x14\x07' |
10 14 07 |
||
8 |
清空缓冲区 |
DLE DC4 8 |
3 |
'\x10\x14\x08' |
10 14 08 |
||
9 |
实时状态传输 |
DLE EOT |
n |
3 |
1<=n<=4 |
'\x10\x04' |
10 04 |
10 |
实时打印机请求 |
DLE ENQ |
n |
3 |
1<=n<=2 |
'\x10\x05' |
10 05 |
11 |
页模式下打印数据 |
ESC FF |
2 |
'\x1B\x0C' |
1B 0C |
||
12 |
设置右测字符间距 |
ESC SP |
2 |
'\x1B\x20' |
1B 20 |
||
13 |
选择打印模式 |
ESC ! |
n |
3 |
0<=n<=255 |
'\x1B\x21' |
1B 21 |
14 |
设置绝对打印位置 |
ESC $ |
nL nH |
4 |
0<=nL<=255,0<=nH<=255 |
'\x1B\x24' |
1B 24 |
15 |
选择|取消用户自定义字符集 |
ESC % |
n |
3 |
0<=n<=255 |
'\x1B\x25' |
1B 25 |
16 |
定义用户自定义字符 |
ESC & |
y c1 c2 [x1 d1...d(y × x1)]...[xk d1...d(y ×xk)] |
255 |
y = 332<=c1<=c2<=1260<=x<=12 (当设定字型A (12<=24)时)0<=x<=9 (当设定字型B (9<=17)时)0<=d1...d(y×xk)<=255 |
'\x1B\x26' |
1B 26 |
17 |
选择位图模式 |
ESC * |
m nL nH d1... dk |
255 |
m = 0,1,32,330<=nL<=255,0<=nH<=30<=d<=255 |
'\x1B\x2A' |
1B 2A |
18 |
设定|解除下划线 |
ESC - |
2 |
'\x1B\x2D' |
1B 2D |
||
19 |
选择缺省行间距 |
ESC 2 |
2 |
'\x1B\x32' |
1B 32 |
||
20 |
设置行间距 |
ESC 3 |
n |
3 |
0<=n<=255 |
'\x1B\x33' |
1B 33 |
21 |
选择周边设备 |
ESC = |
2 |
'\x1B\x3D' |
1B 3D |
||
22 |
取消用户自定义字符 |
ESC ? |
n |
3 |
32<=n<=126 |
'\x1B\x3F' |
1B 3F |
23 |
初始化打印机 |
ESC @ |
2 |
'\x1B\x40' |
1B 40 |
||
24 |
设置水平TAB定位点 |
ESC D |
n1 . . . nk NUL |
255 |
1<=n<=255,0<=k<=32 |
'\x1B\x44' |
1B 44 |
25 |
设定|解除粗体打印 |
ESC E |
2 |
'\x1B\x45' |
1B 45 |
||
26 |
设定|解除重叠打印 |
ESC G |
2 |
'\x1B\x47' |
1B 47 |
||
27 |
打印并进纸 |
ESC J |
n |
3 |
0<=n<=255 |
'\x1B\x4A' |
1B 4A |
28 |
选择页模式 |
ESC L |
2 |
'\x1B\x4C' |
1B 4C |
||
29 |
选择字型 |
ESC M |
2 |
'\x1B\x4D' |
1B 4D |
||
30 |
选择国际字符集 |
ESC R |
2 |
'\x1B\x52' |
1B 52 |
||
31 |
选择标准模式 |
ESC S |
2 |
'\x1B\x53' |
1B 53 |
||
32 |
页模式下选择打印方向 |
ESC T |
2 |
'\x1B\x54' |
1B 54 |
||
33 |
设置|解除顺时针90°旋转 |
ESC V |
2 |
'\x1B\x56' |
1B 56 |
||
34 |
页模式下设置打印区域 |
ESC W |
2 |
'\x1B\x57' |
1B 57 |
||
35 |
设置相对打印位置 |
ESC \ |
nL nH |
4 |
0<=nL<=255,0<=nH<=255 |
'\x1B\x5C' |
1B 5C |
36 |
选择对齐方式 |
ESC a |
n |
3 |
0<=n<=2,48<=n<=50 |
'\x1B\x61' |
1B 61 |
37 |
选择打印纸传感器以输出“缺纸”信号 |
ESC c 3 |
n |
4 |
0<=n<=255 |
'\x1B\x63\x33' |
1B 63 33 |
38 |
选择打印纸传感器以停止打印 |
ESC c 4 |
n |
4 |
0<=n<=255 |
'\x1B\x63\x34' |
1B 63 34 |
39 |
激活|禁止面板按键 |
ESC c 5 |
n |
4 |
0<=n<=255 |
'\x1B\x63\x35' |
1B 63 35 |
40 |
打印并进纸n行 |
ESC d |
n |
3 |
0<=n<=255 |
'\x1B\x64' |
1B 64 |
41 |
全切 |
ESC i |
2 |
'\x1B\x69' |
1B 69 |
||
42 |
产生指定脉冲 |
ESC p |
2 |
'\x1B\x70' |
1B 70 |
||
43 |
选择字符代码表 |
ESC t |
n |
3 |
0<=n<=5,16<=n<=19,n = 255 |
'\x1B\x74' |
1B 74 |
44 |
向主机传送周边设备状态 |
ESC u |
2 |
'\x1B\x75' |
1B 75 |
||
45 |
向主机传送打印纸传感器状态 |
ESC v |
2 |
'\x1B\x76' |
1B 76 |
||
46 |
设置|解除颠倒打印模式 |
ESC í |
2 |
'\x1B\x7B' |
1B 7B |
||
47 |
选择字体 |
Fs G |
2 |
'\x1C\x47' |
1C 47 |
||
48 |
下载一个BMP文件 |
Fs B |
2 |
'\x1C\x42' |
1C 42 |
||
49 |
打印二维码 |
Fs k |
2 |
'\x1C\x6B' |
1C 6B |
||
50 |
二维码XY规格 |
Fs H |
2 |
'\x1C\x48' |
1C 48 |
||
51 |
强制进纸 |
Fs A |
2 |
'\x1C\x41' |
1C 41 |
||
52 |
强制退纸 |
Fs R |
2 |
'\x1C\x52' |
1C 52 |
||
53 |
定义PDF417的方向 |
Fs C |
2 |
'\x1C\x43' |
1C 43 |
||
54 |
定义PDF417的ECC级别 |
Fs D |
2 |
'\x1C\x44' |
1C 44 |
||
55 |
页模式构建下的垂直与水平栏数 |
Fs E |
2 |
'\x1C\x45' |
1C 45 |
||
56 |
设置汉字字符打印模式组合 |
FS ! |
n |
3 |
0<=n<=<=255 |
'\x1C\x21' |
1C 21 |
57 |
设定汉字模式 |
FS & |
2 |
'\x1C\x26' |
1C 26 |
||
58 |
设定|解除汉字下划线 |
FS - |
2 |
'\x1C\x2D' |
1C 2D |
||
59 |
解除汉字模式 |
FS . |
2 |
'\x1C\x2E' |
1C 2E |
||
60 |
定义用户自定义中文字符 |
FS 2 |
2 |
'\x1C\x32' |
1C 32 |
||
61 |
选择汉字字符编码系统 |
FS C |
2 |
'\x1C\x43' |
1C 43 |
||
62 |
设置全角汉字字间距 |
FS S |
2 |
'\x1C\x53' |
1C 53 |
||
63 |
设定|解除四倍角中文打印 |
FS W |
n |
3 |
0<=n<=255 |
'\x1C\x57' |
1C 57 |
64 |
将标记打印纸进纸到打印起始位置 |
GS FF |
2 |
'\x1D\x0C' |
1D 0C |
||
65 |
打印NV位图 |
FS p |
n m |
4 |
1<=n<=255,0<=m<=3 ,48<=m<=51 |
'\x1C\x70' |
1C 70 |
66 |
定义NV位图 |
FS q |
n [xL xH yL yH d1...dk]1...[xL xH yL yH d1...dk]n |
255 |
1<=n<=255,0<=xL<=255,0<=xH<=3 (当 1<=(xL<=xH<=256)<=10230<=yL<=255,0<=yH<=1 (当 1<=(yL<=yH<=256)<=2880<=d<=255k = (xL<=xH<=256)<=(yL<=yH<=256)<=8总计定义的数据区 = 192K 字节 |
'\x1C\x71' |
1C 71 |
67 |
执行测试打印 |
GS ( A |
3 |
'\x1D\x28\x41' |
1D 28 41 |
||
68 |
NV存储用户编辑 |
GS ( C |
3 |
'\x1D\x28\x43' |
1D 28 43 |
||
69 |
用户设置命令 |
GS ( E |
3 |
'\x1D\x28\x45' |
1D 28 45 |
||
70 |
设置调整值 |
GS ( F |
3 |
'\x1D\x28\x46' |
1D 28 46 |
||
71 |
请求传送响应 |
GS ( H |
3 |
'\x1D\x28\x48' |
1D 28 48 |
||
72 |
选择打印控制模式 |
GS ( K |
3 |
'\x1D\x28\x4B' |
1D 28 4B |
||
73 |
自定义打印机控制值 |
GS ( M |
3 |
'\x1D\x28\x4D' |
1D 28 4D |
||
74 |
设置并打印符号 |
GS ( k |
3 |
'\x1D\x28\x6B' |
1D 28 6B |
||
75 |
设定字符大小 |
GS ! |
n |
3 |
0<=n<=255(1<=垂直倍数<=8,1<=水平倍数<=8) |
'\x1D\x21' |
1D 21 |
76 |
页模式下设置绝对垂直打印位置 |
GS $ |
2 |
'\x1D\x24' |
1D 24 |
||
77 |
页模式下设置相对垂直打印位置 |
GS \ |
2 |
'\x1D\x5C' |
1D 5C |
||
78 |
定义下传位图 |
GS * |
x y d1..d( x y 8 ) |
255 |
1<=x<=2551<=y<=48 (x<=y<=1536)0<=d<=255 |
'\x1D\x2A' |
1D 2A |
79 |
运行宏 |
GS ^ |
r t m |
5 |
0<=r<=255,0<=t<=255m<=0,1 |
'\x1D\x2A' |
1D 2A |
80 |
打印下传位图 |
GS / |
m |
3 |
0<=m<=3,48<=m<=51 |
'\x1D\x2F' |
1D 2F |
81 |
开始|结束宏定义 |
GS : |
2 |
'\x1D\x3A' |
1D 3A |
||
82 |
设定|解除反白打印模式 |
GS B |
2 |
'\x1D\x42' |
1D 42 |
||
83 |
设定计数值打印模式 |
GS C 0 |
3 |
'\x1D\x43\x00' |
1D 43 00 |
||
84 |
选择计数模式(A) |
GS C 1 |
3 |
'\x1D\x43\x01' |
1D 43 01 |
||
85 |
设置计数值 |
GS C 2 |
3 |
'\x1D\x43\x02' |
1D 43 02 |
||
86 |
选择计数模式(B) |
GS C ; |
3 |
'\x1D\x43\x3B' |
1D 43 3B |
||
87 |
选择打印头控制模式 |
GS E |
2 |
'\x1D\x45' |
1D 45 |
||
88 |
选择HRI字符的打印位置 |
GS H |
n |
3 |
0<=n<=3,48<=n<=51 |
'\x1D\x48' |
1D 48 |
89 |
传送打印机ID |
GS I |
n |
3 |
1<=n<=3,49<=n<=51 |
'\x1D\x49' |
1D 49 |
90 |
设定左侧空白量 |
GS L |
nL nH |
4 |
0<=nL<=255,0<=nH<=255 |
'\x1D\x4C' |
1D 4C |
91 |
设置垂直和水平运动单位 |
GS P |
2 |
'\x1D\x50' |
1D 50 |
||
92 |
设置打印位置为打印行起点 |
GS T |
2 |
'\x1D\x54' |
1D 54 |
||
93 |
选择裁纸模式并半切割裁纸 |
GS V |
m (n) |
4 |
① m = 1,49② m = 66,0<=n<=255 |
'\x1D\x56' |
1D 56 |
94 |
设置打印区域宽度 |
GS W |
nL nH |
4 |
0<=nL<=255,0<=nH<=255 |
'\x1D\x57' |
1D 57 |
95 |
允许|禁止自动状态回复(ASB) |
GS a |
n |
3 |
'\x1D\x61' |
1D 61 |
|
96 |
设置|解除平滑模式 |
GS b |
2 |
'\x1D\x62' |
1D 62 |
||
97 |
打印计数值 |
GS c |
2 |
\x1D\x63' |
1D 63 |
||
98 |
选择HRI字符字型 |
GS f |
n |
3 |
n<=<=1,48,49 |
'\x1D\x66' |
1D 66 |
99 |
设置条形码高度 |
GS h |
n |
3 |
1<=n<=255 |
'\x1D\x68' |
1D 68 |
100 |
打印条形码 |
GS k |
k m d1 . dk NUL ②GS k m n d1 . dn |
255 |
① 0<=m<=6 (k 和d 取决于使用的条形码系统)② 65<=m<=73 (n 和 d 取决于使用的条形码系统) |
'\x1D\x6B' |
1D 6B |
101 |
传送状态 |
GS r |
n |
3 |
n = 1,49 |
'\x1D\x72' |
1D 72 |
102 |
打印光栅位图 |
GS v 0 |
m xL xH yL yH d1 ... Dk |
255 |
0<=m<=3,48<=m<=510<=xL<=255,0<=xH<=255 在此 1<=(xL + xH<=256)<=1280<=yL<=255,0<=yH<=8 在此 1<=(yL + yH<=256)<=40950<=d ?255k = (xL + xH<=256)<=(yL + yH<=256) (k<=0) |
'\x1D\x76\x00' |
1D 76 00 |
103 |
设置条形码宽度 |
GS w |
n |
3 |
2<=n<=6 |
'\x1D\x77' |
1D 77 |
XLS版本《ESC/POS指令整理表》
参见
hasyimibhar/escpos-printer:C library for operating thermal printers by sending ESC/POS commands
- epson18162eu.zip:FTP上指令版本兼容性参考资料
- TECHNICAL WORKSHOP VII ESC/POS - 爱普生
- :Java实现网络小票打印机自定义无驱打印 thermal_printer