智能餐厅 之 (收银小票打印)

Web收银小票打印基本流程

Created with Raphaël 2.1.2 用户 用户 web web server server winform壳 winform壳 点击打印按钮 调用打印服务 组装打印报文ESC指令,再用Base64编码 通过goeasy推送,web前端 再根据打印类型调用TCP\USB\COM打印

思路:通过java server组装ESC样式和指令,然后通过推送到web前段,前段通过js调用到winform壳的方法分发 TCP\USB\COM打印指令。

package com.takeout.service.print.impl;
/**
 * 打印基本指令
 */
public class PrinterCmdUtils {
     public static byte ESC = 27;    // 换码
     public static byte FS = 28;    // 文本分隔符
     public static byte GS = 29;    // 组分隔符
     public static byte DLE = 16;    // 数据连接换码
     public static byte EOT = 4;    // 传输结束
     public static byte ENQ = 5;    // 询问字符
     public static byte SP = 32;    // 空格
     public static byte HT = 9;    // 横向列表
     public static byte LF = 10;    // 打印并换行(水平定位)
     public static byte CR = 13;    // 归位键
     public static byte FF = 12;    // 走纸控制(打印并回到标准模式(在页模式下) )
     public static byte CAN = 24;    // 作废(页模式下取消打印数据 )

     /**
      * 打印纸一行最大的字节
      */
     private  int LINE_BYTE_SIZE = 32;
     /**
      * 分隔符
      */
     private  String SEPARATOR = "$";
     private static StringBuilder sb = new StringBuilder();

     /**
      * 打印机初始化
      * 
      * @return
      */
     public static byte[] init_printer()
     {
         byte[] result = new byte[2];
         result[0] = ESC;
         result[1] = 64;
         return result;
     }

     /**
      * 打开钱箱
      * 
      * @return
      */
     public static byte[] open_money()
     {
         byte[] result = new byte[5];
         result[0] = ESC;
         result[1] = 112;
         result[2] = 48;
         result[3] = 64;
         result[4] = 0;
         return result;
     }

     /**
      * 换行
      * 
      * @param lineNum要换几行
      * @return
      */
     public static byte[] nextLine(int lineNum)
     {
         byte[] result = new byte[lineNum];
         for (int i = 0; i < lineNum; i++)
         {
             result[i] = LF;
         }

         return result;
     }


     /**
      * 绘制下划线(1点宽)
      * 
      * @return
      */
     public static byte[] underlineWithOneDotWidthOn()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 45;
         result[2] = 1;
         return result;
     }

     /**
      * 绘制下划线(2点宽)
      * 
      * @return
      */
     public static byte[] underlineWithTwoDotWidthOn()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 45;
         result[2] = 2;
         return result;
     }

     /**
      * 取消绘制下划线
      * 
      * @return
      */
     public static byte[] underlineOff()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 45;
         result[2] = 0;
         return result;
     }


     /**
      * 选择加粗模式
      * 
      * @return
      */
     public static byte[] boldOn()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 69;
         result[2] = 0xF;
         return result;
     }

     /**
      * 取消加粗模式
      * 
      * @return
      */
     public static byte[] boldOff()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 69;
         result[2] = 0;
         return result;
     }


     /**
      * 左对齐
      * 
      * @return
      */
     public static byte[] alignLeft()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 97;
         result[2] = 0;
         return result;
     }

     /**
      * 居中对齐
      * 
      * @return
      */
     public static byte[] alignCenter()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 97;
         result[2] = 1;
         return result;
     }

     /**
      * 右对齐
      * 
      * @return
      */
     public static byte[] alignRight()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 97;
         result[2] = 2;
         return result;
     }

     /**
      * 水平方向向右移动col列
      * 
      * @param col
      * @return
      */
     public static byte[] set_HT_position(byte col)
     {
         byte[] result = new byte[4];
         result[0] = ESC;
         result[1] = 68;
         result[2] = col;
         result[3] = 0;
         return result;
     }

     /**
      * 字体变大为标准的n倍
      * 
      * @param num
      * @return
      */
     public static byte[] fontSizeSetBig(int num)
     {
         byte realSize = 0;
         switch (num)
         {
            case 0:
                realSize = 0;
                break;
             case 1:
                 realSize = 1;
                 break;
             case 2:
                 realSize = 17;
                 break;
             case 3:
                 realSize = 34;
                 break;
             case 4:
                 realSize = 51;
                 break;
             case 5:
                 realSize = 68;
                 break;
             case 6:
                 realSize = 85;
                 break;
             case 7:
                 realSize = 102;
                 break;
             case 8:
                 realSize = 119;
                 break;
         }
         byte[] result = new byte[3];
         result[0] = 29;
         result[1] = 33;
         result[2] = realSize;
         return result;
     }

     /**
      * 字体取消倍宽倍高
      * 
      * @return
      */
     public static byte[] fontSizeSetSmall()
     {
         byte[] result = new byte[3];
         result[0] = ESC;
         result[1] = 33;

         return result;
     }

     /**
      * 进纸并全部切割
      * 
      * @return
      */
     public static byte[] feedPaperCutAll()
     {
         byte[] result = new byte[4];
         result[0] = GS;
         result[1] = 86;
         result[2] = 65;
         result[3] = 0;
         return result;
     }

     /**
      * 进纸并切割(左边留一点不切)
      * 
      * @return
      */
     public static byte[] feedPaperCutPartial()
     {
         byte[] result = new byte[4];
         result[0] = GS;
         result[1] = 86;
         result[2] = 66;
         result[3] = 0;
         return result;
     }

     /*
     public static byte[] bmpToByte(Bitmap bmp)
     {
         int h = bmp.Height / 24 + 1;
         int w = bmp.Width;
         byte[][] all = new byte[4 + 2 * h + h * w][];

         all[0] = new byte[] { 0x1B, 0x33, 0x00 };

         Color pixelColor;
         // ESC * m nL nH 点阵图  
         byte[] escBmp = new byte[] { 0x1B, 0x2A, 0x21, (byte)(w % 256), (byte)(w / 256) };

         // 每行进行打印  
         for (int i = 0; i < h; i++)
         {
             all[i * (w + 2) + 1] = escBmp;
             for (int j = 0; j < w; j++)
             {
                 byte[] data = new byte[] { 0x00, 0x00, 0x00 };
                 for (int k = 0; k < 24; k++)
                 {
                     if (((i * 24) + k) < bmp.Height)
                     {
                         pixelColor = bmp.GetPixel(j, (i * 24) + k);
                         if (pixelColor.R == 0)
                         {
                             data[k / 8] += (byte)(128 >> (k % 8));
                         }
                     }
                 }
                 all[i * (w + 2) + j + 2] = data;
             }
             //换行  
             all[(i + 1) * (w + 2)] = PrinterCmdUtils.nextLine(1);
         }
         all[h * (w + 2) + 1] = PrinterCmdUtils.nextLine(2);
         all[h * (w + 2) + 2] = PrinterCmdUtils.feedPaperCutAll();
         all[h * (w + 2) + 3] = PrinterCmdUtils.open_money();

         return PrinterCmdUtils.byteMerger(all);
     }
     */

     // ------------------------切纸-----------------------------
     /*
     public static byte[] byteMerger(byte[] byte_1, byte[] byte_2)
     {
         byte[] byte_3 = new byte[byte_1.Length + byte_2.Length];
         System.Array.Copy(byte_1, 0, byte_3, 0, byte_1.Length);
         System.Array.Copy(byte_2, 0, byte_3, byte_1.Length, byte_2.Length);
         return byte_3;
     }

     public static byte[] byteMerger(byte[][] byteList)
     {
         int Length = 0;
         for (int i = 0; i < byteList.Length; i++)
         {
             Length += byteList[i].Length;
         }
         byte[] result = new byte[Length];

         int index = 0;
         for (int i = 0; i < byteList.Length; i++)
         {
             byte[] nowByte = byteList[i];
             for (int k = 0; k < byteList[i].Length; k++)
             {
                 result[index] = nowByte[k];
                 index++;
             }
         }
         return result;
     }

     public static byte[][] byte20Merger(byte[] bytes)
     {
         int size = bytes.Length / 10 + 1;
         byte[][] result = new byte[size][];
         for (int i = 0; i < size; i++)
         {
             byte[] by = new byte[((i + 1) * 10) - (i * 10)];
             //从bytes中的第 i * 10 个位置到第 (i + 1) * 10 个位置;
             System.Array.Copy(bytes, i * 10, by, 0, (i + 1) * 10);
             result[i] = by;
         }
         return result;
     }
     */
}

打印样式示例

/**
 * 结账单 - 门店
 * shop_name 店名
 * order_type_and_source 桌号:小桌01、[桌牌:39]、[自提--流水号:02341]、[外带--流水号:36252]
 * cashier 收银员
 * meal_num
 * order_num
 * order_time 时间
 * order_goods
 * order_other
 * order_orgin_money
 * order_should_pay_money
 * order_real_pay_money
 * shop_phone
 * shop_address
 * @return
 */
protected String shopBillContent50() {
    // TODO Auto-generated method stub
    StringBuffer content = new StringBuffer();

    content.append("<CENTER>@shop_name</CENTER><BR>");
    content.append("<TITLE>结账单</TITLE><BR>");
    content.append("<CB>@order_type_and_source</CB><BR>");
    content.append("单号:@order_no<BR>");
    content.append("收银员:@cashier<BR>");
    content.append("用餐人数:@meal_num<BR>");
    content.append("时间:@order_time<BR>");
    content.append("------------------------------<BR>");
    content.append("菜品名称     数量   原价  金额<BR>");
    content.append("------------------------------<BR>");
    content.append("@order_goods");
    content.append("------------------------------<BR>");
    content.append("消费总额:@order_orgin_money元<BR>");
    content.append("@order_other");
    content.append("应收金额:@order_should_pay_money元<BR>");
    content.append("@order_pay_item");
    content.append("实收金额:@order_real_pay_money元<BR>");
    content.append("--------------------------------<BR>");
    content.append("签名:<BR>");
    content.append("门店电话:@shop_phone<BR>");
    content.append("门店地址:@shop_address<BR>");
    return content.toString();
}
/**
 * 格式化数据
 * @throws UnsupportedEncodingException 
 * @throws SQLException 
 */
private String prepareContent(String content, PrinterConfigBean pcBean, PrinterUniversalConfigBean uconfig) throws UnsupportedEncodingException, SQLException {
    String msg = content;

    msg = msg.replaceAll("<TITLE>", new String(b_center,"GBK") + new String(PrinterCmdUtils.fontSizeSetBig(2),"GBK"));//放大居中
    msg = msg.replaceAll("</TITLE>", new String(PrinterCmdUtils.fontSizeSetBig(0),"GBK") + new String(b_nextLine,"GBK") + new String(b_left,"GBK"));//结束

    if(uconfig.getFontSize().equals(MyConstant.BIG)) {
        msg = msg.replaceAll("<L>", new String(PrinterCmdUtils.fontSizeSetBig(1),"GBK"));
        msg = msg.replaceAll("</L>", new String(PrinterCmdUtils.fontSizeSetBig(0),"GBK"));
        msg = msg.replaceAll("<CB>", new String(PrinterCmdUtils.fontSizeSetBig(2),"GBK"));
        msg = msg.replaceAll("</CB>", new String(PrinterCmdUtils.fontSizeSetBig(0),"GBK"));
    } else {
        msg = msg.replaceAll("<L>", "");
        msg = msg.replaceAll("</L>", "");
        msg = msg.replaceAll("<CB>", "");
        msg = msg.replaceAll("</CB>", "");
    }
    msg = msg.replaceAll("<BR>", new String(b_nextLine,"GBK"));
    msg = msg.replaceAll("<CENTER>", new String(b_center,"GBK"));
    msg = msg.replaceAll("</CENTER>", new String(b_nextLine,"GBK") + new String(b_left,"GBK"));
    msg = msg.replaceAll("<CUT>", new String(b_breakAll,"GBK"));
    msg = msg.replaceAll("<OPENMONEY>", new String(b_openMoney,"GBK"));
    return Base64.encode(msg, "GBK");
}

通过上面介绍,可以获得基本打印指令的Base64编码后字符串。然后通过goeasy推送到web页面,再通过调用js,进入壳方法,进行解码转发就好了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值