uni-app 蓝牙打印, CPCL指令集使用

news2024/12/26 22:57:20

先上代码:

GitHub - byc233518/uniapp-bluetooth-printer-demo: 使用uniApp 连接蓝牙打印机 Demo, CPCL 指令简单实用示例

(内含 芝珂,佳博,精臣 多个厂家指令集使用文档)

文件结构:


├── App.vue 
├── CPCL 指令手册.pdf  // 指令集参考手册
├── LICENSE
├── README.md
├── libs
│   └── print.js // uni-app打印插件
├── main.js // Demo 入口文件
├── manifest.json // uni-app 
├── node_modules // 依赖
├── pages 
│   ├── index 
│   │   └── index.vue // Demo 页面, 业务上使用可参考此文件
│   └── setting
│   └── index.vue // 打印机连接, 可以集成到应用的系统设置功能
├── pages.json // 页面配置文件
├── uni.scss // uni-app 样式文件
└── yarn.lock

运行方法:

  1. 将代码解压缩, 导入到HBuilderX中;
  2. 连接手机;
  3. 运行到手机或模拟器--运行到Android App 基座;
  4. 待运行完毕, 在 蓝牙设置 界面点击“搜索设备”并进行连接;
  5. 点击”Demo界面”按钮跳转到Demo, 填写表单信息后点击”打印测试”按钮进行测试;

   

集成步骤:

  1. Demo  libs/print.js 复制到项目目录下;
  2. 参考Demo  pages/setting/index.vue 在项目合适位置集成打印机连接配置功能, 一般在系统设置;
  3. 在需要的文件中引用 libs/print.js  print 方法;
  4. 拼接指令集, 见demo, 更多使用方法参见 CPCL 指令集变成文档.pdf ;
  5. 调用 打印插件的 print 方法进行打印,入参为 打印机ID  拼接好的指令集字符串;

代码解析:

*************************************************libs/print.js***********************************************


/**

 * 打印

 * @param mac_address 打印机ID

 * @param data 指令集字符串, 为了灵活起见, 指令集在业务代码中进行转换然后传递进来

 */

export const print = (mac_address, data) => {

    var that = this

    if (!mac_address) {

        uni.showModal({

            title: "提示",

            content: "请选择蓝牙打印机",

            showCancel: false,

        })

        return

    }

    if (!data) {

        uni.showModal({

            title: "提示",

            content: "请提供打印数据.",

            showCancel: false,

        })

        return

    }



    main = plus.android.runtimeMainActivity()

    BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter")

    var UUID = plus.android.importClass("java.util.UUID")

    uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")

    BAdapter = BluetoothAdapter.getDefaultAdapter()

    if (!BAdapter.isEnabled()) {

        uni.showModal({

            title: "提示",

            content: "蓝牙处于关闭状态,是否打开?",

            success: (_) => {

                if (_.confirm) {

                    BAdapter.enable()

                }

            },

        })

        console.log("蓝牙处于关闭状态,正在打开...")

        return

    }



    device = BAdapter.getRemoteDevice(mac_address)

    plus.android.importClass(device)

    bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid)

    plus.android.importClass(bluetoothSocket)

    if (!bluetoothSocket.isConnected()) {

        console.log("检测到设备未连接,尝试连接....")

        bluetoothSocket.connect()

    }

    console.log("设备已连接")

    if (bluetoothSocket.isConnected()) {

        var outputStream = bluetoothSocket.getOutputStream()

        plus.android.importClass(outputStream)

        outputStream.write([0x1b, 0x40]) //打印复位

        outputStream.flush()



        var bytes = plus.android.invoke(data, "getBytes", "gbk") /*utf-8*/



        outputStream.write(bytes)

        outputStream.flush()



        device = null //这里关键

        bluetoothSocket.close()

    }

}

******************************************pages/index/index.vue******************************************

<template>
	<view>
		<view>
			<view>
				<input v-model="formData.name" class="uni-input" placeholder="公司名称" />
				<input v-model="formData.model" class="uni-input" placeholder="车型" />
				<input v-model="formData.code" class="uni-input" placeholder="条码" />
				<input v-model="formData.line" class="uni-input" placeholder="产线" />
				<input v-model="formData.box" class="uni-input" placeholder="箱号" />
				<input v-model="formData.date" class="uni-input" placeholder="日期" />
				<input v-model="formData.operator" class="uni-input" placeholder="装箱人" />
				<input v-model="formData.auditor" class="uni-input" placeholder="确认人" />
			</view>
			<view class="buttos-bar">
				<button class="plain-button plain-button--blue" @click="printTest">打印测试</button>
				<navigator url="/pages/setting/index" hover-class="navigator-hover">
					<button type="default">跳转到设置界面</button>
				</navigator>
			</view>
		</view>
	</view>
	</view>
</template>

<script>
	// 引入打印插件的打印方法
	import {
		print
	} from '@/libs/print.js'

	export default {
		name: 'PrintDemo',
		data() {
			return {
				// 业务数据
				formData: {
					name: "xxx配件有限公司",
					model: "型号123456789",
					code: "编码123456789",
					line: "产线1",
					box: "序号1",
					date: "2023/11/15",
					operator: "操作人",
					auditor: "审核人",
				}
			}
		},
		methods: {
			printTest() {
				// 从缓存中获取已经连接的打印机信息
				var printerid = uni.getStorageSync('ble_printerId')
				if (printerid) {
					if (printerid != null && printerid.length > 0) {
						
						const data = this.formData
						
						// 标签开始, 固定开头, 详见 指令集文档
						var str = " ! 0 200 200 350 1 " + '\r\n';
						// 设置打印纸张宽度
						str += "PAGE-WIDTH 600" + '\r\n';
						
						// 标签内容
						// 文本 {command} {font} {size} {x} {y} {data}
						str += "TEXT 24 0 30 50 " + data.name +"\r\n";
						// 二维码 {command} {type} {x} {y} [M n] [U n] {data}
						str += "B QR 380 20 M 2 U 5" + '\r\n';
						str += "MA," + data.code +"\r\n";
						str += "ENDQR" + '\r\n';
						
						str += "TEXT 24 0 30 100 车型: " + data.model +"\r\n";
						str += "TEXT 24 0 30 150 条码编号:" + data.code +"\r\n";
						str += "TEXT 24 0 320 150 生产线号:" + data.line +"\r\n";
						str += "TEXT 24 0 30 200 装箱序号:" + data.box +"\r\n";
						str += "TEXT 24 0 320 200 日期:" + data.date +"\r\n";
						str += "TEXT 24 0 30 250 装箱人:" + data.operator +"\r\n";
						str += "TEXT 24 0 320 250 确认人:" + data.auditor +"\r\n";
							
						// 标签结束
						str += "GAP-SENSE" + '\r\n';
						str += "FORM " + '\r\n';
						str += "PRINT " + '\r\n';
						
						// 指令集拼接完成, 调用打印插件打印方法进行打印
						print(printerid, str);
					}
				} else {
					uni.showModal({
						title: '提示',
						content: '请先选择已配对的蓝牙打印机, 再进行测试.',
						showCancel: false
					})
				}
			},
		},
	}
</script>

<style scoped lang="scss">
	.uni-input {
		margin-top: 10px;
		height: 30px;
		border: 1px solid #eee;
	}
</style>

****************************************pages/setting/index.vue******************************************

方法解释:

searchDevices  //开始搜寻附近的蓝牙外围设备

onConn // 连接打印机

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1217821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JAVA-排列组合】一个套路速解排列组合题

说明 在初遇排列组合题目时&#xff0c;总让人摸不着头脑&#xff0c;但是做多了题目后&#xff0c;发现几乎能用同一个模板做完所有这种类型的题目&#xff0c;大大提高了解题效率。本文简要介绍这种方法。 题目列表 所有题目均从leetcode查找&#xff0c;便于在线验证 46.…

Mindomo Desktop for Mac(免费思维导图软件)下载

Mindomo Desktop for Mac是一款免费的思维导图软件&#xff0c;适用于Mac电脑用户。它可以帮助你轻松创建、编辑和共享思维导图&#xff0c;让你的思维更加清晰、有条理。 首先&#xff0c;Mindomo Desktop for Mac具有直观易用的界面。它采用了Mac独特的用户界面设计&#xf…

2023年首届天府杯数学建模国际大赛问题A思路详解与参考代码:大地测量数据中异常现象的特征和识别

地球变形观测是固体潮汐曲线分析和地震前体研究的重要手段&#xff0c;也是地球观测技术的重要组成部分。基于各种精密科学仪器的变形观测点主要集中在洞穴、地下井等易的自然灾害&#xff08;雷暴、强降雨、降雪等&#xff09;&#xff0c;人工维护、人工爆破等外部条件&#…

浅谈安科瑞无线测温产品在巴西某工厂的应用

摘 要&#xff1a;高压开关设备是变电站和配电站中保证电力系统安全运行的重要设备之一,因此,开关柜的稳定运行对于整个电力系统有非常重要的意义。设备老化、长期高负荷运行都可能使设备局部温度过高而发生火灾&#xff0c;因此,对变电站内的敏感设备进行温度检测变得尤为重要…

chrome 浏览器个别字体模糊不清

特别是在虚拟机里&#xff0c;有些字体看不清&#xff0c;但是有些就可以&#xff0c;设置办法&#xff1a; chrome://settings/fonts 这里明显可以看到有些字体就是模糊的状态&#xff1a; 把这种模糊的字体换掉即可解决一部分问题。 另外&#xff0c;经过观察&#xff0c;…

Unity开发之C#基础-集合(字典)(Dictionary)

前言 Hello 兄弟们 一转眼俩月又过去了&#xff08;失踪人口回归&#xff09; 不出意外的是出意外了 失踪了两个月 有点对不起我这为数不多的粉丝们 实不相瞒忙的焦头烂额 也没心情写博客 实在对不住各位 好了长话短说 今天这篇文章是讲解c#当中的新的一种集合的表现&#xff…

​软考-高级-系统架构设计师教程(清华第2版)【第10章 软件架构的演化和维护(P345~382)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第10章 软件架构的演化和维护&#xff08;P345~382&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

idea运行项目之后一直卡在Writing classes… 解决方案

最近遇到idea里直接运行一个Spring boot项目后&#xff0c;idea一直慢悠悠的parsing java&#xff0c;然后就writing classes&#xff0c;然后就一直卡着不动了&#xff0c;运气好10几分钟能把项目启动起来。 多年的摸鱼经验告诉我&#xff0c;事出反常必有妖&#xff0c;赶紧…

python趣味编程-5分钟实现一个测验应用程序(含源码、步骤讲解)

Python测验是用 Python 编程语言编写的,这个关于 Python 编程的简单测验是一个简单的项目,用于测试一个人在给定主题考试中的知识能力。 Python 中的 Quiz项目仅包含用户端。用户必须先登录或注册才能开始Python 测验。 此外,还规定了解决问题的时间。用户应在时间结束前解…

Python---列表 集合 字典 推导式(本文以 字典 为主)

推导式&#xff1a; 推导式comprehensions&#xff08;又称解析式&#xff09;&#xff0c;是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列&#xff08;一个有规律的列表或控制一个有规律列表&#xff09;的结构体。 共有三种推导&#xff1a;列表…

系列七、JVM的内存结构【堆(Heap)】

一、概述 一个JVM实例只存在一个堆内存&#xff0c;堆内存的大小是可以手动调节的。类加载器读取了类文件后&#xff0c;需要把类、方法、常变量放到堆内存中&#xff0c;保存所有引用类型的真实信息&#xff0c;以方便执行器执行&#xff0c;堆内存分为三个部分&#xff0c;即…

人工智能基础_机器学习040_Sigmoid函数详解_单位阶跃函数与对数几率函数_伯努利分布---人工智能工作笔记0080

然后我们再来详细说一下Sigmoid函数,上面的函数的公式 我们要知道这里的,Sigmoid函数的意义,这逻辑斯蒂回归的意义就是,在多元线性回归的基础上,把 多元线性回归的结果,缩放到0到1之间对吧,根据中间的0.5为分类,小于0.5的一类,大于的一类, 这里的h theta(x) 就是概率函数 然…

python内置模块subprocess 模块,创建和管理子进程

一、简介 subprocess 是 Python 标准库中的一个模块&#xff0c;用于创建和管理子进程。它提供了一种在 Python 程序中启动新进程、连接到它们的输入/输出/错误管道以及获取它们的返回值的方法。 使用 subprocess 模块&#xff0c;你可以在 Python 程序中执行外部命令、调用其…

【第2章 Node.js基础】2.7 Node.js 的流(一) 可读流

&#x1f308; Node.js 的流 &#x1f680;什么是流 流不是 Node.js 特有的概念。它们是几十年前在 Unix 操作系统中引入的。 我们可以把流看作这些数据的集合&#xff0c;就像液体一样&#xff0c;我们先把这些液体保存在一个容器里&#xff08;流的内部缓冲区 BufferList&…

【Android】设置全局标题栏

序言 在做项目的时候&#xff0c;有时候需要一个全局统一的标题栏&#xff0c;保证项目风格的统一&#xff0c;但是如果在每个activity上面都写一遍这个标题栏就很麻烦了&#xff0c;我们经常用的方法就是写个基类Activity&#xff0c;然后当某个Activity需要这个统一的标题栏…

我记不住的getopt_long的那些参数和返回值

前言&#xff1a;最近在学习面向Linux系统进行C语言的编程&#xff0c;通过查询man手册和查看网络上的各种文章来获取一点点的知识&#xff0c;重点是看完手册还是一脸懵逼&#xff0c;搞不懂手册里面再说啥&#xff0c;而本篇文章将记录一下学习getopt_long的那些参数和返回值…

NFTScan 正式上线 Viction NFTScan 浏览器和 NFT API 数据服务

2023 年 11 月 16 号&#xff0c;NFTScan 团队正式对外发布了 Viction NFTScan 浏览器&#xff0c;将为 Viction 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商&#xff0c;Viction 是继 Bitcoin、Ethereum、BN…

GUI编程--PyQt5--QTreeWidget

文章目录 树型控件展示数据修改节点数据获取所有节点的数据 Qt模组参考 QWidgets QTreeWidget 树型控件展示数据 展示数据的同时&#xff0c;每个节点标注数据类型。 class MyWindow(QWidget):def __init__(self, title):super(MyWindow, self).__init__()self.setWindowTitl…

qt笔记之qml和C++的交互系列(一):初记

code review! —— 杭州 2023-11-16 夜 文章目录 一.qt笔记之qml和C的交互&#xff1a;官方文档阅读理解0.《Overview - QML and C Integration》中给出五种QML与C集成的方法1.Q_PROPERTY&#xff1a;将C类的成员变量暴露给QML2.Q_INVOKABLE()或public slots&#xff1a;将C类…

【面试经典150 | 数学】回文数

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;反转一半数字 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本…