Java实现POS打印机自定义无驱打印

热敏打印机使用越来越广泛,而安装驱动相当复杂,万幸的是,几乎所有的热敏打印机都支持ESC/P指令,参考网络上一些资料后,在此整理了一份自定义打印的方案

• 打印模板

为了增强打印效果的通用性,因此需要提供多元化的模板对齐支持,而且不同大小的打印机所需的版式也不尽相同

模板采用Json格式存储,分为header、goods、bill、footer四个部分,对模板的解析采用号称史上最快的阿里出品的fastjson

模板示例

{
"header": [
{
"text": "{$shopname}",
"size": 2,
"bold": true,
"format": 1,
"line": 2,
"underline": true,
"type": 0
},
{
"text": "{$barCode}",
"format": 1,
"line": 2,
"type": 1
},
{
"path": "{$logo}",
"format": 1,
"line": 2,
"type": 3
},
{
"text": "{$qrCode}",
"format": 1,
"line": 2,
"type": 2
}
],
"goods": [
{
"name": "商品名",
"width": 24,
"format": 0,
"variable": "name"
},
{
"name": "数量",
"width": 8,
"format": 1,
"variable": "num"
},
{
"name": "单价",
"width": 8,
"format": 1,
"variable": "price"
},
{
"name": "金额",
"width": 8,
"format": 2,
"variable": "pay"
}
],
"bill": [
{
"text": "实收现金",
"size": 3,
"bold": true,
"format": 1,
"line": 2,
"underline": false,
"type": 0
},
{
"text": "{$cash}",
"size": 3,
"bold": true,
"format": 1,
"line": 2,
"underline": false,
"type": 0
}
],
"footer": [
{
"text": "详情请访问官网",
"size": 2,
"bold": true,
"format": 1,
"line": 2,
"underline": true,
"type": 0
},
{
"text": "http://www.sublulu.com",
"format": 1,
"line": 2,
"type": 2
}
]
}

模板的代码结构如上所示,可见每个部分均是Json数组

header、bill、footer三部分的结构一模一样,只是位置和内容有所差异
goods区域的数组里面每个元素都对应四个相同的属性
类似{$logo}是模板中指定的占位符,能够更好的支持个性化

模板参数规则

goods参数详解

    /**
* 列名
*/
private String name; /**
* 排版格式
*/
private int format; /**
* 列宽
* 58mm 每行32个半角字符
* 80mm 每行48个半角字符
*/
private int width; /**
* 占位符
* e.g {$time}
*/
private String variable;

• 打印参数

打印根据模板和打印参数合成按照顺序进行打印

打印参数替换模板中的占位符

打印参数解析商品信息进行输出

参数示例

{
"keys": {
"shopname": "黄太吉",
"barCode": "6921734976505",
"qrCode": "http://www.sublulu.com",
"time": "15:35",
"num": 14,
"cash": 324.5,
"logo": "/sdcard/qr.png",
"adv": "关注微信,有大大地活动哦"
},
"goods": [
{
"name": "鱼香肉丝",
"num": 1,
"price": 12.8,
"pay": 12.8
},
{
"name": "葱油粑粑",
"num": 1,
"price": 4.8,
"pay": 4.8
},
{
"name": "辣椒炒肉",
"num": 1,
"price": 14.8,
"pay": 14.8
}
]
}

打印参数的代码结构如上所示,主要分为keys和goods两个部分:

keys中的值负责替换模板中的占位符,如果模板中有,keys中没有则将占位符原样输出

goods中的参数对用模板中的goods的每个属性

打印效果

• 使用示例

打印工具采用单例模式

考虑可能要操作多个打印机,所以以每个ip为key,单例本身为value值

获取EscPos实例

/**
* ip为打印机IP,需要配置
* 端口默认为9100,请勿随意修改
* 编码默认为“GBK”,传入打印机支持的编码
*/
EscPos.getInstance(String ip);
EscPos.getInstance(String ip, int port);
EscPos.getInstance(String ip, int port, String encoding); EscConfig escConfig = new EscConfig(String ip);
EscConfig escConfig = new EscConfig(String ip, int ip);
EscConfig escConfig = new EscConfig(String ip, int ip, String encoding);
EscPos.getInstance(escConfig);

以上为几种获取EscPos实例的代码,EscConfig是对打印机的全局配置项,其详情如下:

// 1 58mm 2. 80mm 默认为2
private int type; // 最后退纸几行 默认为4
private int line; // 打印机ip
private String host; // 打印机端口 默认为9100
private int port; // 打印机的编码格式 默认为"GBK"
private String encoding;

打印示例

所有常用打印命令已经封装完毕,执行打印操作的代码十分简单,如下所示:

// 获取EscPos实例
EscPos.getInstance("192.168.1.110"); // 根据模板内容和打印参数执行打印命令
EscPos.print(template, param);

• 打印流程

EscPos工具类对外质保路了两种方法,且均为静态方法:

  • getInstance()及其重载,用于获取对象实例
  • print(String template, String param),用于打印小票

使用起来相当方便,但其流程略显复杂

打印主流程图

goods打印流程图

header、bill、footer打印主流程图

参考资料:https://github.com/SubLuLu/thermal_printer

Java实现POS打印机自定义无驱打印的更多相关文章

  1. Java使用POS打印机(无驱)

    使用原因:应项目要求,需要使用打印机,但是如果使用Windows驱动来实现打印,在某些条件下会发生网络堵塞等,而且没有提示,所以为了确保信息的完整,避免数据丢失.我们使用无驱打印(直接写端口的方法), ...

  2. Java 实现 POS 打印机无驱打印

    来源:https://www.ibm.com/developerworks/cn/java/j-lo-pos/index.html 行业需求 我们是一家专业做酒店餐饮软件的公司,餐饮软件一个重要的功能 ...

  3. 【转】C#使用ESC指令控制POS打印机打印小票

    .前言 C#打印小票可以与普通打印机一样,调用PrintDocument实现.也可以发送标注你的ESC指令实现.由于 调用PrintDocument类时,无法操作使用串口或TCP/IP接口连接的pos ...

  4. C#使用ESC指令控制POS打印机打印小票

    1.前言 C#打印小票可以与普通打印机一样,调用PrintDocument实现.也可以发送标注你的ESC指令实现.由于 调用PrintDocument类时,无法操作使用串口或TCP/IP接口连接的po ...

  5. Java读取打印机自定义纸张.

    打印出现截断? 对于自定义纸张打印, 一定要先在打印机配置那边添加, 不然会出现截断. 例如打印1000*500, 出来是正常的, 打印216*139, 出现了截断. 因为java默认的打印, 会从打 ...

  6. Java jacob调用打印机打印word文档

    前面说了Java如何生成复杂的Word文档,今年记录下Java如何调用打印机打印word文档. 起初用的是自带的PrintJob,但是系统提供的打印机制并不成熟完整.网上的代码也是千篇一律,在我的打印 ...

  7. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

  8. 树莓派3b无驱动打印

    Linux系统下很少有对打印机做驱动支持,自己做起来又有非常麻烦,还好大多数打印机都能够支持escpos协议,因此我们可以做到无驱动打印. 1.安装python-usb库 git clone http ...

  9. 如何在pyqt中自定义无边框窗口

    前言 之前写过很多关于无边框窗口并给窗口添加特效的博客,按照时间线罗列如下: 如何在pyqt中实现窗口磨砂效果 如何在pyqt中实现win10亚克力效果 如何在pyqt中通过调用SetWindowCo ...

随机推荐

  1. POJ2533&&1836&&3176

    终于写完了POJ的DP专题,然而都是水题233 这次也把题目分了一下,先挑3道特别简单的讲一下 2533 题意:求最长上升子序列. 很简单,用一般的DP或者二分优化都可以过去 这里懒得写一般DP了,其 ...

  2. HTML基础之DOM操作

    DOM(Document Object Model 文档对象模型) 一个web页面的展示,是由html标签组合成的一个页面,dom对象实际就是将html标签转换成了一个文档对象.可以通过dom对象中j ...

  3. CSS快速入门-基本选择器

    1.标签选择器 通过标签进行元素选择. <style> a { font-size:10px; color:red; } </style> 2.* *代表通配符,匹配任意标签, ...

  4. 微信小程序获取客户端系统信息

    微信小程序中有个API: wx.getSystemInfo() 可以获取系统的信息 wx.getSystemInfoSync()===>同步获取系统信息 wx.getSyatemInfo({ s ...

  5. SSM整合配置(Spring+Spring MVC+Mybatis)

    一.配置准备   通过Maven工程,在eclipse中整合SSM,并在Tomcat服务器上运行 在进行配置前,先理清楚要配置哪些文件,如图,除web.xml外,其余三个配置文件名称均可自定义: 如图 ...

  6. 172. Remove Element【LintCode by java】

    Description Given an array and a value, remove all occurrences of that value in place and return the ...

  7. js执行问题

    金三银四搞事季,前端这个近年的热门领域,搞事气氛特别强烈,我朋友小伟最近就在疯狂面试,遇到了许多有趣的面试官,有趣的面试题,我来帮这个搞事 boy 转述一下. 以下是我一个朋友的故事,真的不是我. f ...

  8. PAT甲题题解-1005. Spell It Right (20)-数位求和,水

    把每个位上的数字求和sum,然后以英文单词的形式输出sum的每个位 #include <iostream> #include <cstdio> #include <alg ...

  9. (第十二周)Bug修正报告

    根据Debug周各组找出的Bug,现做出如下说明: Bug: 一.天天向上团队 看到的现象:当食物链长度很长时,最长链显示不全.如下图: 期待的现象:当食物链过长时,食物链可以自动换行. 二者的差异: ...

  10. 第二阶段冲刺——seven

    个人任务: 马佳慧:设计界面背景,统一风格. 王金萱:整体运行测试上传到公网上的程序. 季方:修改优化已上传的代码. 司宇航:整体调试程序继续优化. 站立会议: 任务看板和燃尽图: