当前位置: 移动技术网 > IT编程>移动开发>Android > Android打印机--小票打印格式及模板设置实例代码

Android打印机--小票打印格式及模板设置实例代码

2019年07月24日  | 移动技术网IT编程  | 我要评论

中华龙飞,千面公主复仇记,文章儿子照片

小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式需要去查询对应打印机的api文档,这里我把常用的api给封装了一下

  1. 文字对齐方式
  2. 打印字体大小
  3. 字体是否加粗
  4. 打印二维码
  5. 打印条形码
  6. 切纸
  7. 打开钱箱
  8. 字符串转字节数组
  9. 字符拼接

printformatutils.java

/**
 * 打印格式
 * created by john on 17-3-23.
 */

public class printformatutils {
  // 对齐方式
  public static final int align_left = 0;   // 靠左
  public static final int align_center = 1;  // 居中
  public static final int align_right = 2;  // 靠右

  //字体大小
  public static final int font_normal = 0;  // 正常
  public static final int font_middle = 1;  // 中等
  public static final int font_big = 2;    // 大

  //加粗模式
  public static final int font_bold = 0;       // 字体加粗
  public static final int font_bold_cancel = 1;    // 取消加粗

  /**
   * 打印二维码
   * @param qrcode
   * @return
   */
  public static string getqrcodecmd(string qrcode) {
    byte[] data;
    int store_len = qrcode.length() + 3;
    byte store_pl = (byte) (store_len % 256);
    byte store_ph = (byte) (store_len / 256);

    // qr code: select the model
    //       hex   1d   28   6b   04   00   31   41   n1(x32)   n2(x00) - size of model
    // set n1 [49 x31, model 1] [50 x32, model 2] [51 x33, micro qr code]
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=140
    byte[] modelqr = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x04, (byte)0x00, (byte)0x31, (byte)0x41, (byte)0x32, (byte)0x00};

    // qr code: set the size of module
    // hex   1d   28   6b   03   00   31   43   n
    // n depends on the printer
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=141
    byte[] sizeqr = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x43, (byte)0x08};

    //     hex   1d   28   6b   03   00   31   45   n
    // set n for error correction [48 x30 -> 7%] [49 x31-> 15%] [50 x32 -> 25%] [51 x33 -> 30%]
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=142
    byte[] errorqr = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x45, (byte)0x31};

    // qr code: store the data in the symbol storage area
    // hex   1d   28   6b   pl   ph   31   50   30   d1...dk
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=143
    //            1d     28     6b     pl     ph cn(49->x31) fn(80->x50) m(48->x30) d1…dk
    byte[] storeqr = {(byte)0x1d, (byte)0x28, (byte)0x6b, store_pl, store_ph, (byte)0x31, (byte)0x50, (byte)0x30};

    // qr code: print the symbol data in the symbol storage area
    // hex   1d   28   6b   03   00   31   51   m
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=144
    byte[] printqr = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x51, (byte)0x30};

    data = bytemerger(modelqr, sizeqr);
    data = bytemerger(data, errorqr);
    data = bytemerger(data, storeqr);
    data = bytemerger(data, qrcode.getbytes());
    data = bytemerger(data, printqr);

    return new string(data);
  }

  /**
   * 打印条码
   * @param barcode
   * @return
   */
  public static string getbarcodecmd(string barcode) {
    // 打印 code-128 条码时需要使用字符集前缀
    // "{a" 表示大写字母
    // "{b" 表示所有字母,数字,符号
    // "{c" 表示数字,可以表示 00 - 99 的范围


    byte[] data;

    string btencode;

    if (barcode.length() < 18) {
      // 字符长度小于15的时候直接输出字符串
      btencode = "{b" + barcode;
    } else {
      // 否则做一点优化

      int startpos = 0;
      btencode = "{b";

      for (int i = 0; i < barcode.length(); i++) {
        char curchar = barcode.charat(i);

        if (curchar < 48 || curchar > 57 || i == (barcode.length() - 1)) {
          // 如果是非数字或者是最后一个字符

          if (i - startpos >= 10) {
            if (startpos == 0) {
              btencode = "";
            }

            btencode += "{c";

            boolean isfirst = true;
            int numcode = 0;

            for (int j = startpos; j < i; j++) {

              if (isfirst) { // 处理第一位
                numcode = (barcode.charat(j) - 48) * 10;
                isfirst = false;
              } else { // 处理第二位
                numcode += (barcode.charat(j) - 48);
                btencode += (char) numcode;
                isfirst = true;
              }

            }

            btencode += "{b";

            if (!isfirst) {
              startpos = i - 1;
            } else {
              startpos = i;
            }
          }

          for (int k = startpos; k <= i; k++) {
            btencode += barcode.charat(k);
          }
          startpos = i + 1;
        }

      }
    }


    // 设置 hri 的位置,02 表示下方
    byte[] hriposition = {(byte) 0x1d, (byte) 0x48, (byte) 0x02};
    // 最后一个参数表示宽度 取值范围 1-6 如果条码超长则无法打印
    byte[] width = {(byte) 0x1d, (byte) 0x77, (byte) 0x02};
    byte[] height = {(byte) 0x1d, (byte) 0x68, (byte) 0xfe};
    // 最后两个参数 73 : code 128 || 编码的长度
    byte[] barcodetype = {(byte) 0x1d, (byte) 0x6b, (byte) 73, (byte) btencode.length()};
    byte[] print = {(byte) 10, (byte) 0};

    data = printformatutils.bytemerger(hriposition, width);
    data = printformatutils.bytemerger(data, height);
    data = printformatutils.bytemerger(data, barcodetype);
    data = printformatutils.bytemerger(data, btencode.getbytes());
    data = printformatutils.bytemerger(data, print);

    return new string(data);
  }

  /**
   * 切纸
   * @return
   */
  public static string getcutpapercmd() {
    // 走纸并切纸,最后一个参数控制走纸的长度
    byte[] data = {(byte) 0x1d, (byte) 0x56, (byte) 0x42, (byte) 0x15};

    return new string(data);
  }

  /**
   * 对齐方式
   * @param alignmode
   * @return
   */
  public static string getaligncmd(int alignmode) {
    byte[] data = {(byte) 0x1b, (byte) 0x61, (byte) 0x0};
    if (alignmode == align_left) {
      data[2] = (byte) 0x00;
    } else if (alignmode == align_center) {
      data[2] = (byte) 0x01;
    } else if (alignmode == align_right) {
      data[2] = (byte) 0x02;
    }

    return new string(data);
  }

  /**
   * 字体大小
   * @param fontsize
   * @return
   */
  public static string getfontsizecmd(int fontsize) {
    byte[] data = {(byte) 0x1d, (byte) 0x21, (byte) 0x0};
    if (fontsize == font_normal) {
      data[2] = (byte) 0x00;
    } else if (fontsize == font_middle) {
      data[2] = (byte) 0x01;
    } else if (fontsize == font_big) {
      data[2] = (byte) 0x11;
    }

    return new string(data);
  }

  /**
   * 加粗模式
   * @param fontbold
   * @return
   */
  public static string getfontboldcmd(int fontbold) {
    byte[] data = {(byte) 0x1b, (byte) 0x45, (byte) 0x0};

    if (fontbold == font_bold) {
      data[2] = (byte) 0x01;
    } else if (fontbold == font_bold_cancel) {
      data[2] = (byte) 0x00;
    }

    return new string(data);
  }

  /**
   * 打开钱箱
   * @return
   */
  public static string getopendrawercmd() {
    byte[] data = new byte[4];
    data[0] = 0x10;
    data[1] = 0x14;
    data[2] = 0x00;
    data[3] = 0x00;

    return new string(data);
  }

  /**
   * 字符串转字节数组
   * @param str
   * @return
   */
  public static byte[] stringtobytes(string str) {
    byte[] data = null;

    try {
      byte[] strbytes = str.getbytes("utf-8");

      data = (new string(strbytes, "utf-8")).getbytes("gbk");
    } catch (unsupportedencodingexception exception) {
      exception.printstacktrace();
    }

    return data;
  }

  /**
   * 字节数组合并
   * @param bytesa
   * @param bytesb
   * @return
   */
  public static byte[] bytemerger(byte[] bytesa, byte[] bytesb) {
    byte[] bytes = new byte[bytesa.length + bytesb.length];
    system.arraycopy(bytesa, 0, bytes, 0, bytesa.length);
    system.arraycopy(bytesb, 0, bytes, bytesa.length, bytesb.length);
    return bytes;
  }
}

有了打印格式,还要对具体的打印小票设置打印模板,主要就是利用上面的打印格式工具类,进行字符或字符串拼接,设置文字间空格的长度,以及使用换行符换行等。

有些小票打印的内容有可能是通用的,比如底部结束语–可能是公司宣传语或广告语,这些内容是否展示需要根据具体需求加以控制,还有二维码、条形码打印,是否切纸等需要根据实际场景取舍,所以最好封装一个打印配置类,以控制打印内容显示。

/**
 * 打印模板
 */
public class printcontract {

  /**
   * 打印内容
   */
  public static stringbuilder createxxtxt(string ...) {

    stringbuilder builder = new stringbuilder();

    //设置大号字体以及加粗
    builder.append(printformatutils.getfontsizecmd(printformatutils.font_big));
    builder.append(printformatutils.getfontboldcmd(printformatutils.font_bold));

    // 标题
    builder.append("title");
    //换行,调用次数根据换行数来控制
    addlineseparator(builder);

    //设置普通字体大小、不加粗
    builder.append(printformatutils.getfontsizecmd(printformatutils.font_normal));
    builder.append(printformatutils.getfontboldcmd(printformatutils.font_bold_cancel));

    //内容
    ......

    //设置某两列文字间空格数, x需要计算出来
    addidenticalstrtostringbuilder(builder, x, " ");

    //切纸
    builder.append(printformatutils.getcutpapercmd());

    return builder;
  }

  /**
   * 向stringbuilder中添加指定数量的相同字符
   *
   * @param printcount  添加的字符数量
   * @param identicalstr 添加的字符
   */

  private static void addidenticalstrtostringbuilder(stringbuilder builder, int printcount, string identicalstr) {
    for (int i = 0; i < printcount; i++) {
      builder.append(identicalstr);
    }
  }

  /**
   * 根据字符串截取前指定字节数,按照gbk编码进行截取
   *
   * @param str 原字符串
   * @param len 截取的字节数
   * @return 截取后的字符串
   */
  private static string substringbygbk(string str, int len) {
    string result = null;
    if (str != null) {
      try {
        byte[] a = str.getbytes("gbk");
        if (a.length <= len) {
          result = str;
        } else if (len > 0) {
          result = new string(a, 0, len, "gbk");
          int length = result.length();
          if (str.charat(length - 1) != result.charat(length - 1)) {
            if (length < 2) {
              result = null;
            } else {
              result = result.substring(0, length - 1);
            }
          }
        }
      } catch (exception e) {
        e.printstacktrace();
      }
    }
    return result;
  }

  /**
   * 添加换行符
   */
  private static void addlineseparator(stringbuilder builder) {
    builder.append("\n");
  }

  /**
   * 在gbk编码下,获取其字符串占据的字符个数
   */
  private static int getcharcountbygbkencoding(string text) {
    try {
      return text.getbytes("gbk").length;
    } catch (exception e) {
      e.printstacktrace();
      return 0;
    }
  }


  /**
  * 打印相关配置
  */
  public static class printconfig {
    public int maxlength = 30;

    public boolean printbarcode = false; // 打印条码
    public boolean printqrcode = false;  // 打印二维码
    public boolean printendtext = true;  // 打印结束语
    public boolean needcutpaper = false; // 是否切纸
  }

}

有了打印模板,接下来就是调用打印设备打印方法发送打印指令

//调用打印机打印方法,传入上面某个小票打印模板返回的字符串
string str = printcontract.createxxtxt(...);
printer.print(str, null);

//打开钱箱方法
printer.print(printformatutils.getopendrawercmd(), null);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网