uni-app 使用蓝牙打印机ESC/POS指令基础方法

uni-app 使用蓝牙打印机ESC/POS指令基础方法

最近项目使用uniapp的框架,发布Android APP,业务连接蓝牙打印机,参考网上的资料,写的都不错,使用借鉴了一个博主的内容,打印后发现打印结果格式控制不对。
由于测试的打印机,没有说明,后来查找资料,找到了生产厂家的信息:兼容ESC/POS指令集, 更多字符样式设置指令。那么问题在于解决打印指令。

打印指令

可以找到很多说明的资料
打印指令,又称打印控制命令。计算机通过打印控制语言,以软件命令的方法来控制打印机操作,解释执行打印数据,获得打印结果的。对于打印机所实现的复杂功能而言,打印控制语言是基础。它直接关系到打印输入质量的优劣。因为增强我们对打印机控制语言的了解,就可以更好地选择和使用打印机。
目前主流的打印机控制语言只要有三种:
1.Epson公司的ESC命令集(普通打印机)
2.HP公司的PCL命令集
3.Adobe公司的PostScript(简称PS)命令集
其它:CPCL命令集(移动打印机), TSPL命令集(标签打印机)
普通打印机都是ESC指令集
标签打印机这种是TSPL指令集
移动打印机CPCL打印语言
还有其它打印机厂商自己开发的打印机语言许。多厂商都使用自己的打印机控制语言,如EPSON的ESC/page,佳能的CaPSYL,施乐的XES、JDL,IBM的IPDS,DEC的ANSI/Sixel等,它们都各具特点,

好吧,是指令问题。那么怎么使用ESC/POS指令??
很容易就能找到ESC/POS指令内容,但是怎么用呢?原生Android 使用java的有,好像都没有任何uniapp中使用说明。。。

看了代码,其实就是如何组合成命令格式文件,发送给打印机,找了能找的资料,逐个分析,有些是封装了引用,但是没有代码可以看,突然发现一个暴露出来的方法,是不是可以转换自己的,测试了,总算是可以使用了,最基本的ESC/POS指令,组合自己的业务,拼装后给打印机,成功了。

Esc指令工具代码

EscPosUtil.js

//字符串转字节序列
function stringToByte(str) {  
    var bytes = new Array();  
    var len, c;  
    len = str.length;  
    for(var i = 0; i < len; i++) {  
        c = str.charCodeAt(i);  
        if(c >= 0x010000 && c <= 0x10FFFF) {  
            bytes.push(((c >> 18) & 0x07) | 0xF0);  
            bytes.push(((c >> 12) & 0x3F) | 0x80);  
            bytes.push(((c >> 6) & 0x3F) | 0x80);  
            bytes.push((c & 0x3F) | 0x80);  
        } else if(c >= 0x000800 && c <= 0x00FFFF) {  
            bytes.push(((c >> 12) & 0x0F) | 0xE0);  
            bytes.push(((c >> 6) & 0x3F) | 0x80);  
            bytes.push((c & 0x3F) | 0x80);  
        } else if(c >= 0x000080 && c <= 0x0007FF) {  
            bytes.push(((c >> 6) & 0x1F) | 0xC0);  
            bytes.push((c & 0x3F) | 0x80);  
        } else {  
            bytes.push(c & 0xFF);  
        }  
    }  
    return bytes;  
}  

//字节序列转ASCII码
//[0x24, 0x26, 0x28, 0x2A] ==> "$&C*"
 function byteToString(arr) {  
    if(typeof arr === 'string') {  
        return arr;
    }  
    var str = '',  
        _arr = arr;  
    for(var i = 0; i < _arr.length; i++) {  
        var one = _arr[i].toString(2),  
            v = one.match(/^1+?(?=0)/);  
        if(v && one.length == 8) {  
            var bytesLength = v[0].length;  
            var store = _arr[i].toString(2).slice(7 - bytesLength);  
            for(var st = 1; st < bytesLength; st++) {  
                store += _arr[st + i].toString(2).slice(2);  
            }  
            str += String.fromCharCode(parseInt(store, 2));  
            i += bytesLength - 1;  
        } else {  
            str += String.fromCharCode(_arr[i]);  
        }  
    }  
    return str;  
}  
//居中
function Center() {
	var Center = [];
	Center.push(27);
	Center.push(97);
	Center.push(1);
	var strCenter = byteToString(Center);
	return strCenter;
}

//居左
function Left() {
	var Left = [];
	Left.push(27);
	Left.push(97);
	Left.push(48);
	var strLeft = byteToString(Left);
	return strLeft;
}
//标准字体
function Size1() {
	var Size1 = [];
	Size1.push(29);
	Size1.push(33);
	Size1.push(0);
	var strSize1 = byteToString(Size1);
	return strSize1;
}
//大号字体
function Size2(n) {
	var Size2 = [];
	Size2.push(29);
	Size2.push(33);
	Size2.push(n);
	var strSize2 = byteToString(Size2);
	return strSize2;
}

module.exports = {
	Center:Center,
	Left:Left,
	Size1:Size1,
	Size2:Size2,
	byteToString:byteToString,
	stringToByte:stringToByte,
}

使用了js byte[] 和string 相互转换的方法,返回是字符串 形式的内容,提供拼接打印内容。

指令的使用

ESC/POS 控制指令,很容易就能找到,例如
https://www.cnblogs.com/mafeng/p/6292024.html
结合代码和控制指令,来学习下使用。
以ESC a n 选择字符对齐模式例:
在这里插入图片描述

代码对应的内容

//居中
function Center() {
	var Center = [];
	Center.push(27);
	Center.push(97);
	Center.push(1);
	var strCenter = byteToString(Center);
	return strCenter;
}

//居左
function Left() {
	var Left = [];
	Left.push(27);
	Left.push(97);
	Left.push(48);
	var strLeft = byteToString(Left);
	return strLeft;
}

可以看到 使用了十进制的数据
在这里插入图片描述

第三个n值,决定了 对齐方式
在这里插入图片描述

通过该例子,就能理解,指令的使用参数值赋值的方法
居中 27 97 1, 靠左 27 97 0
按照这个思路,看下字体的设置
在这里插入图片描述

29 33 0 基础字体大小,
29 33 n 根据n值变化大小
至于打印的效果,根据业务需要自己配置命令了。这几个基础的命名,满足了基础的使用。

拼接指令使用

import ExcPostUtil from '../../utils/EscPosUtil.js';
//打印内容
printInfo(){
				return new Promise((resolve,reject)=>{
					var strCenter = ExcPostUtil.Center();
					var strLeft = ExcPostUtil.Left();
					var strSize1 = ExcPostUtil.Size1();
					var strSize2 = ExcPostUtil.Size2(16);
					
					let nowdate = utildate.formatTimeaAll(new Date());
					console.log("nowdate="+nowdate)
					let strCmd = strLeft + strSize2 + this.shopName +  "\n";					
					strCmd += strSize1 + "订单号:" + this.orderSN + "\n";
					strCmd += `--------------`+ "\n"+ "\n";
					this.shopcar.forEach(e=>{
						strCmd += strSize2 + `商品:${e.cainame}`+ "\n";
						strCmd += `数量:    ${e.num} `+ "\n";
						strCmd += `价格:${e.price}X${e.num}=${e.price*e.num}元`+ "\n";
						strCmd += `--------------`+ "\n"+ "\n";
					})				
					strCmd +=strSize1 +'合计:      256元' + "\n";
					strCmd +='时间: '+ nowdate + "\n";					
					strCmd += strCenter + this.omessage+ "\n";	
					strCmd += "\n";
					strCmd += "\n";
				    resolve(strCmd);					
				}).then((strCmd) => {
					this.bufferData = strCmd;
					console.log(this.bufferData)					
				}).catch(error => {
					console.log('Error', error);
				})
			},

把bufferData 送给打印机就可以打印了
注意指令要放到每行的 第一个位置。

打印结果

在这里插入图片描述

以上可以使用基本的字体控制、位置控制,满足了基础要求。
原理能知道了,其它的内容 大家可以根据需要自己去测试实现了。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值