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

如果我们用安装 Windows 驱动的方法来实现后厨打印,那么肯定是不行的,因为我们只能单向向驱动程序抛包,不能从驱动程序获得任何返回值,没有办法了解是否打印成功,而且经过验证后发现,热敏打印机驱动打印时速度上非常慢。而且更为严重的是,有时候因为后厨打印机过多,Windows 驱动甚至会因为网络堵塞自作主张将包丢弃,没有任何提示。这在行业应用中是不行的,会给用户带来损失,所以想到了绕过 Windows 驱动,直接写端口的方法。

package com.common.util.portprinter;import java.io.IOException;
import java.io.OutputStream;import com.common.util.PrinterParameterConf;/*** @author ChenMing**/
public class PortPrinterBase {private OutputStream out;protected int lineCount = 40;private String printType="0";public PortPrinterBase(OutputStream out, String printType){this.out = out;this.printType = printType;initPrinter();String lineCountStr = PrinterParameterConf.printerParameterConf.getProperty(PrinterParameterConf.LINEPRINTERCHARCOUNT_NAME);try{int temp = Integer.parseInt(lineCountStr);this.lineCount = temp;}catch(Exception e){    }}protected final String LEFT = "LEFT";protected final String CENTER = "CENTER";protected final String RIGHT = "RIGHT";public static final byte HT = 0x9;public static final byte LF = 0x0A;public static final byte CR = 0x0D;public static final byte ESC = 0x1B;public static final byte DLE = 0x10;public static final byte GS = 0x1D;public static final byte FS = 0x1C;public static final byte STX = 0x02;public static final byte US = 0x1F;public static final byte CAN = 0x18;public static final byte CLR = 0x0C;public static final byte EOT = 0x04;/* 初始化打印机 */ public static final byte[] ESC_INIT = new byte[] {ESC, '@'};/* 设置标准模式 */public static final byte[] ESC_STANDARD = new byte[] {ESC, 'S'};/* 设置汉字打印模式 */public static final byte[] ESC_CN_FONT = new byte[] {FS, '&'};/* 选择字符集 */public static final byte[] ESC_SELECT_CHARACTER = new byte[] {ESC, 'R', 9};/* 设置用户自定义汉字字体 焗7118 */public static final byte[] ESC_FS_2 = new byte[] {FS, 0x32, 0x71, 0x18};/* 取消用户自定义字体 */public static final byte[] ESC_CANCEL_DEFINE_FONT = new byte[]{ESC, '%', 0};/* 打开钱箱指令 */ public static final byte[] ESC_OPEN_DRAWER = new byte[]{ESC, 'p', 0x00, 0x10, (byte) 0xff};/* 切纸指令GS V m   * m  0,48 Executes a full cut(cuts the paper completely)*    1,49 Excutes a partilal cut(one point left uncut)*/ public static final byte[] POS_CUT_MODE_FULL = new byte[]{GS, 'V', 0x00};public static final byte[] POS_CUT_MODE_PARTIAL = new byte[]{GS, 'V', 0x01};/* 西文字符 (半宽)字体A (6 ×12),汉字字符 (全宽)字体A (12×12) */ public static final byte[] ESC_FONT_A = new byte[]{ESC, '!', 0};/* 西文字符 (半宽)字体B (8×16),汉字字符 (全宽)字体B (16×16) */ public static final byte[] ESC_FONT_B = new byte[]{ESC, '!', 1};/* 12*24   0/48*/public static final byte[] ESC_FONTA= new byte[]{ESC, 'M', 48};/* 9*17    1/49*/public static final byte[] ESC_FONTB= new byte[]{ESC, 'M', 1};/* 默认颜色字体指令 */ public static final byte[] ESC_FONT_COLOR_DEFAULT = new byte[] {ESC, 'r', 0x00};/* 红色字体指令 */ public static final byte[] ESC_FONT_COLOR_RED = new byte[] {ESC, 'r', 0x01 };/* 标准大小 */ public static final byte[] FS_FONT_ALIGN = new byte[]{FS, 0x21, 1, ESC, 0x21, 1}; /* 横向放大一倍 */ public static final byte[] FS_FONT_ALIGN_DOUBLE = new byte[]{FS, 0x21, 4, ESC, 0x21, 4}; /* 纵向放大一倍 */ public static final byte[] FS_FONT_VERTICAL_DOUBLE = new byte[]{FS, 0x21, 8, ESC, 0x21, 8, GS, '!', 0x01}; /* 横向纵向都放大一倍 */ public static final byte[] FS_FONT_DOUBLE = new byte[]{FS, 0x21, 12, ESC, 0x21, 48}; /* 靠左打印命令 */ public static final byte[] ESC_ALIGN_LEFT = new byte[]{0x1b,'a', 0x00};/* 居中打印命令 */ public static final byte[] ESC_ALIGN_CENTER = new byte[]{0x1b,'a', 0x01};/* 靠右打印命令 */ public static final byte[] ESC_ALIGN_RIGHT = new byte[]{0x1b,'a', 0x02};/* 字体加粗 */public static final byte[] ESC_SETTING_BOLD = new byte[]{ESC, 0x45, 1};/* 取消字体加粗 */public static final byte[] ESC_CANCEL_BOLD = new byte[]{ESC, 0x45, 0};//DLE EOT n 实时状态传送//如果返回结果为22/*** 、DLE EOT n 实时状态传送[格式] ASCII码 DLE EOT n十六进制码 10 04 n十进制码 16 4 n[范围] 1 ≤ n ≤ 4[描述] 根据下列参数,实时传送打印机状态,参数 n 用来指定所要传送的打印机状态:n = 1:传送打印机状态n = 2:传送脱机状态n = 3:传送错误状态n = 4:传送纸传感器状态[注释] 打印机收到该命令后立即返回相关状态该命令尽量不要插在2个或更多字节的命令序列中。即使打印机被ESC =(选择外设)命令设置为禁止,该命令依然有效。打印机传送当前状态,每一状态用1个字节数据表示。打印机传送状态时并不确认主机是否收到。打印机收到该命令立即执行。该命令只对串口打印机有效。打印机在任何状态下收到该命令都立即执行。*/public static final byte[] PRINT_STATE_DLE_EOT = new byte[] {DLE, EOT,0x01};public void initPrinter(){try {//modify by gongqiyi 20090917 //ESC_INIT 将在清空缓存区的数据//out.write(ESC_INIT);//自定义字体//out.write(ESC_FS_2);out.write(ESC_STANDARD);out.write(ESC_CANCEL_DEFINE_FONT);out.write(ESC_FONTA);out.write(ESC_SELECT_CHARACTER);//进入汉字模式打印//out.write(ESC_CN_FONT);//out.write(ESC_FONT_B);//out.write(ESC_FONTA);} catch (IOException e) {e.printStackTrace();}}/*** 走纸到切纸位置并切纸*/public void executeLineFeedAndPaperCut(){try {out.write(PrinterParameterConf.printerParameterConf.getProperty(PrinterParameterConf.PRINTCUTLINE_NAME).getBytes());out.write(POS_CUT_MODE_PARTIAL);} catch (IOException e) {e.printStackTrace();}}/*** 单据头打印* @param str*/public void billHeaderPrinter(String str){try {out.write(ESC_ALIGN_CENTER);out.write(FS_FONT_DOUBLE);out.write((str+"\n").getBytes());out.write(LF);} catch (IOException e) {e.printStackTrace();}}/*** 叫单号打印* @param str*/public void callNumPrinter(String str){try {out.write(ESC_ALIGN_LEFT);out.write(FS_FONT_DOUBLE);out.write((str+"\n").getBytes());} catch (IOException e) {e.printStackTrace();}}/*** 双倍大小字体* @param str*/public void doubleSizePrinter(String str, String align){try {if(CENTER.equals(align)){out.write(ESC_ALIGN_LEFT);}else if(RIGHT.equals(align)){out.write(ESC_ALIGN_RIGHT);}else{out.write(ESC_ALIGN_LEFT);}out.write(FS_FONT_DOUBLE);out.write((str+"\n").getBytes());//out.write(LF);} catch (IOException e) {e.printStackTrace();}}/*** 标准字体打印一行* @param str 需打印的字符串* @param align 打印的位置 LEFT/CENTER/RIGHT 其他为默认居左打印*/public void standardPrinterLine(String str, String align){try{if(CENTER.equals(align)){out.write(ESC_ALIGN_CENTER);out.write(FS_FONT_ALIGN);out.write(ESC_CN_FONT);out.write(ESC_CANCEL_BOLD);if("1".equals(printType)){out.write(ESC_FONTA);}else{out.write(ESC_FONT_B);}out.write(str.getBytes());}else if(RIGHT.equals(align)){out.write(ESC_ALIGN_RIGHT);out.write(FS_FONT_ALIGN);out.write(ESC_CN_FONT);out.write(ESC_CANCEL_BOLD);if("1".equals(printType)){out.write(ESC_FONTA);}else{out.write(ESC_FONT_B);}out.write(str.getBytes());}else{out.write(ESC_ALIGN_LEFT);out.write(FS_FONT_ALIGN);out.write(ESC_CN_FONT);out.write(ESC_CANCEL_BOLD);if("1".equals(printType)){out.write(ESC_FONTA);}else{out.write(ESC_FONT_B);}out.write(str.getBytes());}out.write("\n".getBytes());}catch(IOException e) {e.printStackTrace();}}/*** 标准粗体字体打印一行* @param str 需打印的字符串* @param align 打印的位置 LEFT/CENTER/RIGHT 其他为默认居左打印*/public void standardBoldPrinterLine(String str, String align){try{if(CENTER.equals(align)){out.write(ESC_ALIGN_CENTER);out.write(FS_FONT_ALIGN);out.write(ESC_CN_FONT);out.write(ESC_SETTING_BOLD);if("1".equals(printType)){out.write(ESC_FONTA);}else{out.write(ESC_FONT_B);}out.write(str.getBytes());}else if(RIGHT.equals(align)){out.write(ESC_ALIGN_RIGHT);out.write(FS_FONT_ALIGN);out.write(ESC_CN_FONT);out.write(ESC_SETTING_BOLD);if("1".equals(printType)){out.write(ESC_FONTA);}else{out.write(ESC_FONT_B);}out.write(str.getBytes());}else{out.write(ESC_ALIGN_LEFT);out.write(FS_FONT_ALIGN);out.write(ESC_CN_FONT);out.write(ESC_SETTING_BOLD);if("1".equals(printType)){out.write(ESC_FONTA);}else{out.write(ESC_FONT_B);}out.write(str.getBytes());}out.write("\n".getBytes());}catch(IOException e) {e.printStackTrace();}}/*** 双倍宽字体按行打印* @param str* @param align*/public void largeSizePrinterLine(String str, String align){try{if(CENTER.equals(align)){out.write(ESC_ALIGN_CENTER);out.write(FS_FONT_ALIGN_DOUBLE);out.write(str.getBytes());}else if(RIGHT.equals(align)){out.write(ESC_ALIGN_RIGHT);out.write(FS_FONT_ALIGN_DOUBLE);out.write(str.getBytes());}else{out.write(ESC_ALIGN_LEFT);out.write(FS_FONT_ALIGN_DOUBLE);out.write(str.getBytes());}out.write("\n".getBytes());}catch(IOException e) {e.printStackTrace();}}/*** 双倍高字体按行打印* @param str* @param align*/public void largeHSizePrinterLine(String str, String align){try{if(CENTER.equals(align)){out.write(ESC_ALIGN_CENTER);out.write(FS_FONT_VERTICAL_DOUBLE);out.write(str.getBytes());}else if(RIGHT.equals(align)){out.write(ESC_ALIGN_RIGHT);out.write(FS_FONT_VERTICAL_DOUBLE);out.write(str.getBytes());}else{out.write(ESC_ALIGN_LEFT);out.write(FS_FONT_VERTICAL_DOUBLE);out.write(str.getBytes());}out.write("\n".getBytes());}catch(IOException e) {e.printStackTrace();}}    /*** 大号字体红色按行打印* @param str* @param align*/public void largeSizeRedPrinterLine(String str, String align){try{if(CENTER.equals(align)){out.write(ESC_ALIGN_CENTER);out.write(FS_FONT_ALIGN_DOUBLE);out.write(ESC_FONT_COLOR_RED);out.write(str.getBytes());}else if(RIGHT.equals(align)){out.write(ESC_ALIGN_RIGHT);out.write(FS_FONT_ALIGN_DOUBLE);out.write(ESC_FONT_COLOR_RED);out.write(str.getBytes());}else{out.write(ESC_ALIGN_LEFT);out.write(FS_FONT_ALIGN_DOUBLE);out.write(ESC_FONT_COLOR_RED);out.write(str.getBytes());}out.write("\n".getBytes());}catch(IOException e) {e.printStackTrace();}}public void openDrawer(){try {out.write(ESC_OPEN_DRAWER);} catch (IOException e) {e.printStackTrace();}}public String makePrintString(int lineChars, String txt1, String txt2){if(txt1 == null){txt1 = "";}if(txt2 == null){txt2 = "";}int spaces = 0;String tab = "";try{spaces = lineChars - (txt1.getBytes().length + txt2.getBytes().length);for (int j = 0 ; j < spaces ; j++){tab += " ";}}catch(Exception e){e.printStackTrace();}return txt1 + tab + txt2;}public String makePrintString(int lineChars, String txt1, String txt2, String txt3){if(txt1 == null){txt1 = "";}if(txt2 == null){txt2 = "";}if(txt3 == null){txt3 = "";}int spaces = 0;int lineChars1 = lineChars*2/3;String tab = "";String returnStr = txt1;try{spaces = lineChars1 - (returnStr.getBytes().length + txt2.getBytes().length);for (int j = 0 ; j < spaces ; j++){tab += " ";}returnStr = txt1 + tab + txt2;spaces = lineChars - (returnStr.getBytes().length + txt3.getBytes().length);tab = "";for (int j = 0 ; j < spaces ; j++){tab += " ";}returnStr = returnStr + tab + txt3;}catch(Exception e){e.printStackTrace();}return returnStr;}
}

Java直接控制打印机打印相关推荐

  1. Linux Centos 7 实现java控制打印机打印文件**

    Linux Centos 7 实现java控制打印机打印文件 设备:Hp LaserJet Pro MFP M126nw 打印机 操作系统: Centos7 yum源:163Centos7 cups版 ...

  2. java实现打印机打印

    1.后台控制打印代码 /** @author Stone */ public class GMMSPrinter implements Printable { private static final ...

  3. java发布后功能不能用,急项目发布后java写的打印功能失效了-求解解决方法

    当前位置:我的异常网» J2EE » 急项目发布后java写的打印功能失效了-求解解决方法 急项目发布后java写的打印功能失效了-求解解决方法 www.myexceptions.net  网友分享于 ...

  4. Java——IO(打印流)

    1,打印字节流(PrintStream)的概述: 打印流可以很方便的将对象的toString()结果输出并且自动加上换行,而且可以使用自动刷出的模式 System.out就是一个PrintStream ...

  5. java趣味题-打印杨辉三角

    java趣味题-打印杨辉三角 public class First105 { public static void main(String[] args) {   int [][] a=new int ...

  6. Java连接打印机打印二维码

    首先导入依赖 implementation 'com.google.zxing:core:3.5.1' implementation 'com.google.zxing:javase:3.5.1' 1 ...

  7. Java之日志打印占位符

    在java中日志打印基本方式有System.out.print()打印,在工程应用中更多的是使用LogFactory,getLogger()打印,下面对其打印时使用占位符的用法进行简单分析. 1.Sy ...

  8. Java 中怎么打印数组?

    分享一道经典Java面试题:   Java 中怎么打印数组? 你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法来打印数组.由于数组没有实现 toSt ...

  9. java项目统一打印入参出参等日志

    java项目统一打印入参出参等日志 1.背景 2.设计思路 3.核心代码 3.1 自定义注解 3.2 实现BeanFactoryPostProcessor接口 3.3 实现MethodIntercep ...

最新文章

  1. Maven国内源设置 - OSChina国内源失效了,别更新了
  2. 智源研究院发布 2020 年世界十大 AI 进展
  3. spring boot配置druid
  4. 数学之美 系列十 有限状态机和地址识别
  5. window SDK自定义安装路径选择
  6. Python 中的万能之王 Lambda 函数
  7. confusion_matrix(混淆矩阵)
  8. c# 结构体 4字节对齐_【专题4:平时遇到的问题】 之 【3.由结构体字节对齐引发的通信故障】...
  9. 为OracleLinux配置FTP yum源
  10. python自动化办公 51cto_利用python实现批量自动化运维脚本案例
  11. 百度回应“宕机”;微信 5 年内出 VR 版?腾讯破解谷歌漏洞 | 极客头条
  12. 接口(interface)有什么优点,为什么要用接口
  13. win7 兼容 因特尔十代_高配主板想用win7咋办 Intel10代CPU配上驱动总裁玩转win7
  14. 切!原来进入500强就那么简单啊——前IBM,HP,Dell员工揭开外企的招聘内幕
  15. 云服务器的带宽是什么意思?怎么选择带宽大小?
  16. SuiteScritp 2.0开发实例 自定义工单+领料单 单据流转 打印
  17. vba根据列名获取列号 获取总列数 求和
  18. c++primer第十六章模板特例化
  19. 嵌入式c语言如何在堆区开辟空间
  20. (转)IST:Iterative Shrinkage/Thresholding和Iterative Soft Thresholding

热门文章

  1. 2020年手机性能榜大洗牌:小米10 Pro勇夺第一!
  2. 每周推荐短视频:谈论“元宇宙”要有严肃认真的态度
  3. 数据建模太难?全美一等奖得主,带你从入门到超神!
  4. 阿里的敏捷组织和中台策略有何不同?
  5. python3爬取教务系统的个人学期课程表(无头谷歌浏览模拟登录)
  6. 【量化投资】策略二(聚宽)
  7. Python开发mysql和mongo 连接类
  8. 本地JAVA开发页面使用AzureAD(AAD)验证登录
  9. LIN Bus | 一个应用广泛的串行通信协议
  10. 找不到支撑位和压力位?看完本文可帮到你