Android打印机--小票打印格式及模板设置实例代码
程序员文章站
2022-05-20 21:55:16
小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式需要去查询对应打印机的api文档,这里我把常用的api给封装了一下
文字对齐方式
打印字体大小...
小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式需要去查询对应打印机的api文档,这里我把常用的api给封装了一下
- 文字对齐方式
- 打印字体大小
- 字体是否加粗
- 打印二维码
- 打印条形码
- 切纸
- 打开钱箱
- 字符串转字节数组
- 字符拼接
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);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 第五讲 庖丁解牛:简历编写的注意事项
下一篇: 生粉的作用原来这么大,你知道吗?