小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式需要去查询对应打印机的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);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# android
# 小票打印机
# 打印小票
# Android实现PDF预览打印功能
# Android gradle插件打印时间戳的方法详解
# Android编程实现计算两个日期之间天数并打印所有日期的方法
# Android中如何安全地打印日志详解
# Mac 下 Android Studio 不打印日志的解决办法
# Android jni调试打印char阵列的实例详解
# Android下的POS打印机调用的简单实现
# Android 蓝牙连接 ESC/POS 热敏打印机打印实例(ESC/POS指令篇)
# Android 蓝牙连接 ESC/POS 热敏打印机打印实例(蓝牙连接篇)
# Android进阶——安卓调用ESC/POS打印机打印实例
# Android手机通过蓝牙连接佳博打印机的实例代码
# Android实现系统打印功能
# 加粗
# 小票
# 换行
# 换行符
# 有可能
# 我把
# 或者是
# 要对
# 装了
# 要使
# 大家多多
# 时需
# 行数
# 指令集
# 宣传语
# 文档
# 打印机打印
# index
# ref_escpos
# epson
相关文章:
在线教育网站制作平台,山西立德教育官网?
如何在服务器上三步完成建站并提升流量?
建站主机与虚拟主机有何区别?如何选择最优方案?
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
如何快速搭建自助建站会员专属系统?
建站主机SSH密钥生成步骤及常见问题解答?
电商网站制作公司有哪些,1688网是什么意思?
C++如何编写函数模板?(泛型编程入门)
网站插件制作软件免费下载,网页视频怎么下到本地插件?
开心动漫网站制作软件下载,十分开心动画为何停播?
seo网站制作优化,网站SEO优化步骤有哪些?
淘宝制作网站有哪些,淘宝网官网主页?
如何用PHP工具快速搭建高效网站?
寿县云建站:智能SEO优化与多行业模板快速上线指南
专业网站建设制作报价,网页设计制作要考什么证?
内网网站制作软件,内网的网站如何发布到外网?
招贴海报怎么做,什么是海报招贴?
如何彻底删除建站之星生成的Banner?
如何通过VPS搭建网站快速盈利?
如何通过云梦建站系统实现SEO快速优化?
如何快速搭建支持数据库操作的智能建站平台?
中山网站制作网页,中山新生登记系统登记流程?
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
如何快速上传自定义模板至建站之星?
自助网站制作软件,个人如何自助建网站?
如何选择高效稳定的ISP建站解决方案?
北京网站制作公司哪家好一点,北京租房网站有哪些?
如何批量查询域名的建站时间记录?
如何快速搭建高效可靠的建站解决方案?
如何通过WDCP绑定主域名及创建子域名站点?
如何在Tomcat中配置并部署网站项目?
网站制作公司,橙子建站是合法的吗?
安徽网站建设与外贸建站服务专业定制方案
无锡营销型网站制作公司,无锡网选车牌流程?
潮流网站制作头像软件下载,适合母子的网名有哪些?
制作电商网页,电商供应链怎么做?
小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?
如何在云指建站中生成FTP站点?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
如何在搬瓦工VPS快速搭建网站?
Python lxml的etree和ElementTree有什么区别
建站主机数据库如何配置才能提升网站性能?
如何注册花生壳免费域名并搭建个人网站?
Python文件管理规范_工程实践说明【指导】
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
如何通过二级域名建站提升品牌影响力?
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
*请认真填写需求信息,我们会在24小时内与您取得联系。