Java 实现 POS 打印机无驱打印

news/2024/11/26 0:33:54/

行业需求

我们是一家专业做酒店餐饮软件的公司,餐饮软件一个重要的功能就是后厨打印问题,前台点菜完毕,后厨立刻打印出单子,这样就减少人工递单的麻烦,节省时间,提高翻台率。这种信息化解决方案对打印技术要求很高,理论上最好 100% 不丢单,也就是每次点菜后厨都会相应出单子,但是实际上行不通,为什么呢?因为网线、打印机、网卡等都有可能有问题,别说打印机等硬件因为厨房油烟问题损坏,我们甚至碰到过网线被老鼠咬断的情况,总之硬件网络故障防不胜防,所以只能退而求其次,就是有问题不可怕,程序能够判断是否出了问题,并能给出提示,便于服务员处理,及时补单。

如果我们用安装 Windows 驱动的方法来实现后厨打印,那么肯定是不行的,因为我们只能单向向驱动程序抛包,不能从驱动程序获得任何返回值,没有办法了解是否打印成功。而且更为严重的是,有时候因为后厨打印机过多,Windows 驱动甚至会因为网络堵塞自作主张将包丢弃,没有任何提示。

这在行业应用中是不行的,会给用户带来损失,所以想到了绕过 Windows 驱动,直接写端口的方法。

无驱打印的可行性

所谓直接写端口的方法,就是不用安装打印机驱动,不使用 PrinterJob 获得打印机的名字的方法进行打印。

众所周知,之所以安装打印机驱动,一个重要的原因就是打印机厂商千差万别,不同的打印机往往都有各自的驱动,很难实现万能驱动。但是,在 POS 打印机行业却有一条捷径,就是现在市面上的 POS 打印机基本上都支持爱普生指令,也就是说,只要将程序和打印机联通,直接向端口里面写爱普生指令就可以控制打印机。

打印机接受到爱普生指令以后,自行进行解析,然后打印出相应的内容。

爱普生指令

日本的 EPSON 公司在目前的 POS 打印机市场,尤其是针式打印机市场占有很大一部分份额。它所推行的 ESC 打印控制命令 (EPSON StandardCode for Pr5nter) 已经成为了针式打印机控制语言事实上的工业标准,ESC/POS 打印命令集是 ESC 打印控制命令的简化版本,现在大多数 POS 打印都采用 ESC/POS 指令集。绝大多数打印机都有 EPSON ESC 的软件命令仿真功能,而且其它打印控制命令的格式和功能也都与 ESC 代码集类似。

由于早期的操作系统 DOS 与现在 Windows 的结构不同,在打印机内部软件和应用软件之间没有由硬件厂商提供的打印驱动程序,必须由应用软件直接通过硬件接口来控制打印机,所以从 ESC 指令出现开始,它就是公开的,否则没有应用软件可以使用它,而除了标准的 ESC 指令外,每种型号的打印机其指令又不太一样,所以在 DOS 软件中,你可以看到每个应用软件都只是支持为数不多的几种常用打印机。

ESC 指令在形式上分为两种格式,一种是文本方式控制码,一种是 Escape 转义序列码。文本方式控制码由一字节字符码表示,实现的是与打印机硬件操作有关的指令,Escape 序列码由转义字符和参数字符或打印数据组成。

建立打印连接

通过上面的介绍,了解了实现无驱打印原来只是一层窗户纸,具体的方法就是首先建立打印机连接,然后写入爱普生指令即可。那么如何建立打印机连接?以网口 POS 打印机举例。

第一步,首先要给网口打印机赋一个 IP 地址,例如叫做 192.168.0.18 。

第二步,编写连接代码。

1
2
3
4
Socket client=new java.net.Socket();
PrintWriter socketWriter;
client.connect(new InetSocketAddress("192.168.0.18" , 9100),1000); // 创建一个 socket
socketWriter = new PrintWriter(client.getOutputStream());// 创建输入输出数据流

看起来跟一般的 socket 连接没有很大的区别,就是赋一个 IP 地址和一个端口号,并设置一下超时时间即可,只需要说明的是,一般 POS 打印机的端口都是 9100 。

写入打印内容

连接建立完毕,写入内容就非常容易,只要使用 write 或者 println 方法写入即可,其中 write 方法是写入数字或字符,println 写入一行字符串。

例如:写入数字 socketWriter.write(0);

写入一行字符串 socketWriter.println( “巧富餐饮软件后厨单据” );

再入一行字符串 socketWriter.println( “桌位 14 桌,人数 3 ” );

再入一行字符串 socketWriter.println( “跺脚鱼头 1 份” );

您或许有疑问?内容已经成功写入,好像我们还没有用到爱普生指令。是的,如果只是普通的写入内容,不需要用到爱普生指令,爱普生指令主要帮助实现放大字体,自动走纸,打印条形码等功能。

放大字体

放大字体需要用到爱普生的 0x1c 指令,使用爱普生指令的方法很简单,只要向端口写入指令即可,例如:

1
socketWriter.write(0x1c);

注意 0x1c,是 16 进制的数字,当然也可以转换成 10 进制来写。需要说明的是,使用爱普生指令放大字体不能随意放大,因为它不是图形化打印,而是文本化打印,所以纵向或者横向只能按照倍数放大,不能矢量放大。例如在 POS58 打印机上将“巧富餐饮软件”几个字放大打印,可以有如下放大方法。

1
2
3
4
5
6
7
8
9
10
11
12
/* 横向放大一倍 */
socketWriter.write(0x1c);
socketWriter.write(0x21);
socketWriter.write(4);
/* 纵向放大一倍 */
socketWriter.write(0x1c);
socketWriter.write(0x21);
socketWriter.write(8);
/* 横向纵向都放大一倍 */
socketWriter.write(0x1c);
socketWriter.write(0x21);
socketWriter.write(12);

一般情况下,我们倾向采用纵向放大一倍的方法,放大后的字体看起来有点像仿宋体,视觉效果还不错。

兼容多种类型打印机

现在知道了使用爱普生指令的方法,所以只要有一本爱普生指令手册在手里,就可以用 Java 控制打印机进行无驱打印。但是现在问题是,同样是爱普生指令,不同的 pos 打印机可能不一样,就拿放大字体来说,pos58 打印机和 pos80 打印机指令就不尽相同。这时候怎么办呢?如何兼容多种类型打印机?

比如说,有的打印机并不是使用 0x1c 作为放大指令,而是使用 0x1b 作为放大指令,怎么办?容易。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 横向放大一倍 */
socketWriter.write(0x1c);
socketWriter.write(0x21);
socketWriter.write(4);
socketWriter.write(0x1b);
socketWriter.write(0x21);
socketWriter.write(4);
/* 纵向放大一倍 */
socketWriter.write(0x1c);
socketWriter.write(0x21);
socketWriter.write(8);
socketWriter.write(0x1b);
socketWriter.write(0x21);
socketWriter.write(8);
/* 横向纵向都放大一倍 */
socketWriter.write(0x1c);
socketWriter.write(0x21);
socketWriter.write(12);
socketWriter.write(0x1b);
socketWriter.write(0x21);
socketWriter.write(12);

看明白了吗?就是写两遍就行,因为如果 0x1b 指令若不存在,打印机自动将其抛弃。

实现自动走纸

POS 打印机因为出纸口有一些深度,打印完毕为了避免撕裂文字内容,一般需要适当走纸才行,当然可以使用爱普生指令来走纸,但是这样并不稳妥,为什么呢 ? 因为要考虑 POS 机的兼容性,所以一般采用打印空行的方式实现走纸。

1
2
3
for(int i=0;i<10;i++){
     socketWriter.println(" ");// 打印完毕自动走纸
}

显然,打印空行的方式有更好地兼容性。

打印条形码

条形码在各个行业中现在有广泛的应用,所以让打印机打印条形码是非常重要的功能,不过你不需要费好多精力去研究条形码知识,因为爱普生指令中有一个打印条形码指令,例如我们要打印条形码“ 091955826335 ”,只要使用如下命令即可。

1
2
3
4
5
6
7
8
9
10
11
socketWriter.write(0x1d);
socketWriter.write(0x68);
socketWriter.write(120);
socketWriter.write(0x1d);
socketWriter.write(0x48);
socketWriter.write(0x01);
socketWriter.write(0x1d);
socketWriter.write(0x6B);
socketWriter.write(0x02);
socketWriter.println "091955826335" );
socketWriter.write(0x00);

完整的代码

好了,下面举一个完整的例子,我们来建立一个叫做 print 的方法,向某个打印机打印一个字符和条形码,并实现自动走纸,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private boolean print(String ip, int port, String str,String code,int skip)
throws Exception{
     Socket client=new java.net.Socket();
     PrintWriter socketWriter;
     client.connect(new InetSocketAddress(ip,port),1000); // 创建一个 socket
     socketWriter = new PrintWriter(client.getOutputStream());// 创建输入输出数据流
     /* 纵向放大一倍 */
     socketWriter.write(0x1c);
     socketWriter.write(0x21);
     socketWriter.write(8);
     socketWriter.write(0x1b);
     socketWriter.write(0x21);
     socketWriter.write(8);
     socketWriter.println(str);
     // 打印条形码
     socketWriter.write(0x1d);
     socketWriter.write(0x68);
     socketWriter.write(120);
     socketWriter.write(0x1d);
     socketWriter.write(0x48);
     socketWriter.write(0x01);
     socketWriter.write(0x1d);
     socketWriter.write(0x6B);
     socketWriter.write(0x02);
     socketWriter.println(code);
     socketWriter.write(0x00);
     for(int i=0;i<skip;i++){
         socketWriter.println(" ");// 打印完毕自动走纸
     }
  }

小结

本文虽然只是讲述了网口打印机的直接写端口方式,似乎对并口打印机无效,其实不是这样,并口打印机只要接一个打印服务器就可以用了,缺点就是非一体机,然后还要安装打印服务器驱动。

这种无驱打印在非常广泛的范围内可以得到应用,包括餐饮、超市、医药等等其他需要用到 POS 打印机的行业。

相关主题

  • “Merlin 的魔力:在 JDK 1.4 中打印,第 1 部分”(developerWorks,2002 年 4 月):介绍 JDK 1.4 为 Java 平台带来了另一套打印功能和技术。
  • “Java 打印程序设计”(developerWorks,2002 年 10 月):介绍 JDK 1.4 提供的一套完整的“Java 打印服务 API”(Java Print Service API)。
  • “用 Java 设计面向对象的打印程序”(developerWorks,2002 年 12 月):如果将打印内容进行对象化分析,设计出面向对象的打印程序,则会更出色地完成打印要求,并且代码很容易重用,事半功倍。
  • 您可以在 developerWorks 的 Java 技术专区 中找到有关 Java 编程各方面知识的文章。

http://www.ppmy.cn/news/138102.html

相关文章

斑马打印机-RFID打印机 ZT411R最全攻略,从0上手 通过【JAVA生成ZPL指令+ts24.lib+ip:端口】的方式调用打印,无须安装驱动

前言&#xff1a;本文如标题所言&#xff0c;主要分享如何通过JAVA调用斑马的RFID进行打印 1.准备 首先得准备好你的RFID打印机、本文实例用得是斑马ZT411 RFID版。根据打印机操作手册完成打印机得安装&#xff0c;其中包括标签和色带安装、以及打印机得配网&#xff08;推荐配…

佳博打印机驱动安装方法

本文以佳博GP-1924D为例和大家分享一下佳博打印机驱动的安装方法 安装前请先将打印机连接好并开机 1、双击运行下载的驱动程序&#xff0c;并按照提示进行解压。 2、在安装界面上点“引导安装” 3、点“下一步” 4、点击“安装驱动” 5、勾选“我同意许可合纸的条款”&#x…

mp2555sp文件服务器,理光mp2555sp驱动

理光mp2555sp打印机驱动是mp2555sp型号打印机所使用的驱动程序&#xff0c;支持windows、MAC、Server三大操作系统&#xff0c;可以完美兼容&#xff0c;帮助电脑视频别印记&#xff0c;因为版本太多了&#xff0c;小编没有整合到一起&#xff0c;大家可以点击下面的官方下载&a…

夏普ar2048s打印机驱动安装_无光盘,轻松解决各种打印机的驱动安装

大家好,我是波仔,感谢大家一起和我分享和探讨。 今天波仔跟大家来一起分享一下,在没有光盘,也没有光驱的情况下,轻松解决各种打印机的驱动安装。 很多家庭或者办公室都有打印机,但是有时候电脑可能会重新安装新的系统,或者是新买的打印机,而电脑又没有光驱,打印机需要…

POS58票据热敏打印机,怎么用ESC/POS命令控制打印

POS58票据热敏打印机&#xff0c;怎么用ESC/POS命令控制打印 时间:2010-09-02 12:43 来源: 作者: 点击: - POS58票据热敏打印机&#xff0c;怎么用ESC/POS命令控制打印文字大小&#xff1f; 使用的是POS58票据热敏打印机&#xff0c;怎么控制文字大小&#xff1f;我知道ESC/POS…

POS58热敏打印解决方法

POS58热敏打印 现在我正在做一个C#Winform的项目&#xff0c;其中想打印小票就和超市的那种效果差不多的&#xff0c;用的打印机是POS58,指令支持ESC/POS;接口是USB接口&#xff0c;我该怎么和打印机通信并控制打印机打印呢&#xff0c;希望高手给个完整的例子或者类似的也行&a…

POS58 票据热敏打印机,怎么用ESC/POS命令控制打印文字大小?

转贴地址&#xff1a;http://www.cnblogs.com/Tmouse/archive/2010/04/14/1711490.html 使用的是POS58票据热敏打印机&#xff0c;怎么控制文字大小&#xff1f; 我知道ESC/POS指令&#xff0c;可不会用。 ASCII &#xff1a;ESC ! n 十 进制 &#xff1a;27 33 n 十六进制&…

BLU58小票打印机win10驱动安装

环境 硬件 BLU58 小票打印机&#xff0c; 支持蓝牙和usb连接。 操作系统 windows 10 驱动安装步骤 安装准备 关闭windows 10 驱动程序强制前面 上一篇文中有说明 驱动文件解压缩 解压客服给的压缩文件 WIN8.WIN10安装流程BLU58.rar 解压POS58_CN.zip 等会需要…