Android进阶——安卓调用ESC/POS打印机打印实例
发布时间 - 2026-01-11 00:33:44 点击率:次前言

前一段时间由于工作需要,要研究一下安卓程序调用打印机打印小票,并且要求不能使用蓝牙调用,研究了一下,可以利用socket连接,来实现打印功能。写了个Demo,分享一下。
工具:一台打印机(芯烨XP-80XX),一台安卓测试机
开发环境:Android Studio 1.5
需求:点击按钮,实现打印小票功能,小票上除必要文字外,还要有二维码。
封装了一个Pos打印工具类:
package com.example.haoguibao.myapplication;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* Created by haoguibao on 16/2/18.
* Description : 封装Pos机打印工具类
* Revision :
*/
public class Pos {
//定义编码方式
private static String encoding = null;
private Socket sock = null;
// 通过socket流进行读写
private OutputStream socketOut = null;
private OutputStreamWriter writer = null;
/**
* 初始化Pos实例
*
* @param ip 打印机IP
* @param port 打印机端口号
* @param encoding 编码
* @throws IOException
*/
public Pos(String ip, int port, String encoding) throws IOException {
sock = new Socket(ip, port);
socketOut = new DataOutputStream(sock.getOutputStream());
this.encoding = encoding;
writer = new OutputStreamWriter(socketOut, encoding);
}
/**
* 关闭IO流和Socket
*
* @throws IOException
*/
protected void closeIOAndSocket() throws IOException {
writer.close();
socketOut.close();
sock.close();
}
/**
* 打印二维码
*
* @param qrData 二维码的内容
* @throws IOException
*/
protected void qrCode(String qrData) throws IOException {
int moduleSize = 8;
int length = qrData.getBytes(encoding).length;
//打印二维码矩阵
writer.write(0x1D);// init
writer.write("(k");// adjust height of barcode
writer.write(length + 3); // pl
writer.write(0); // ph
writer.write(49); // cn
writer.write(80); // fn
writer.write(48); //
writer.write(qrData);
writer.write(0x1D);
writer.write("(k");
writer.write(3);
writer.write(0);
writer.write(49);
writer.write(69);
writer.write(48);
writer.write(0x1D);
writer.write("(k");
writer.write(3);
writer.write(0);
writer.write(49);
writer.write(67);
writer.write(moduleSize);
writer.write(0x1D);
writer.write("(k");
writer.write(3); // pl
writer.write(0); // ph
writer.write(49); // cn
writer.write(81); // fn
writer.write(48); // m
writer.flush();
}
/**
* 进纸并全部切割
*
* @return
* @throws IOException
*/
protected void feedAndCut() throws IOException {
writer.write(0x1D);
writer.write(86);
writer.write(65);
// writer.write(0);
//切纸前走纸多少
writer.write(100);
writer.flush();
//另外一种切纸的方式
// byte[] bytes = {29, 86, 0};
// socketOut.write(bytes);
}
/**
* 打印换行
*
* @return length 需要打印的空行数
* @throws IOException
*/
protected void printLine(int lineNum) throws IOException {
for (int i = 0; i < lineNum; i++) {
writer.write("\n");
}
writer.flush();
}
/**
* 打印换行(只换一行)
*
* @throws IOException
*/
protected void printLine() throws IOException {
writer.write("\n");
writer.flush();
}
/**
* 打印空白(一个Tab的位置,约4个汉字)
*
* @param length 需要打印空白的长度,
* @throws IOException
*/
protected void printTabSpace(int length) throws IOException {
for (int i = 0; i < length; i++) {
writer.write("\t");
}
writer.flush();
}
/**
* 打印空白(一个汉字的位置)
*
* @param length 需要打印空白的长度,
* @throws IOException
*/
protected void printWordSpace(int length) throws IOException {
for (int i = 0; i < length; i++) {
writer.write(" ");
}
writer.flush();
}
/**
* 打印位置调整
*
* @param position 打印位置 0:居左(默认) 1:居中 2:居右
* @throws IOException
*/
protected void printLocation(int position) throws IOException {
writer.write(0x1B);
writer.write(97);
writer.write(position);
writer.flush();
}
/**
* 绝对打印位置
*
* @throws IOException
*/
protected void printLocation(int light, int weight) throws IOException {
writer.write(0x1B);
writer.write(0x24);
writer.write(light);
writer.write(weight);
writer.flush();
}
/**
* 打印文字
*
* @param text
* @throws IOException
*/
protected void printText(String text) throws IOException {
String s = text;
byte[] content = s.getBytes("gbk");
socketOut.write(content);
socketOut.flush();
}
/**
* 新起一行,打印文字
*
* @param text
* @throws IOException
*/
protected void printTextNewLine(String text) throws IOException {
//换行
writer.write("\n");
writer.flush();
String s = text;
byte[] content = s.getBytes("gbk");
socketOut.write(content);
socketOut.flush();
}
/**
* 初始化打印机
*
* @throws IOException
*/
protected void initPos() throws IOException {
writer.write(0x1B);
writer.write(0x40);
writer.flush();
}
/**
* 加粗
*
* @param flag false为不加粗
* @return
* @throws IOException
*/
protected void bold(boolean flag) throws IOException {
if (flag) {
//常规粗细
writer.write(0x1B);
writer.write(69);
writer.write(0xF);
writer.flush();
} else {
//加粗
writer.write(0x1B);
writer.write(69);
writer.write(0);
writer.flush();
}
}
}
其中,打印机的IP和端口号从打印机的属性设置处可查。
MainActivity中进行调用:
package com.example.haoguibao.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//订单菜品集合
private List<FoodsBean> foodsBean;
private Pos pos;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt_print = (Button) findViewById(R.id.button);
bt_print.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 开启一个子线程
new Thread() {
public void run() {
try {
pos = new Pos("IP", 9100, "GBK"); //第一个参数是打印机网口IP
//初始化打印机
pos.initPos();
//初始化订单数据
initData();
pos.bold(true);
pos.printTabSpace(2);
pos.printWordSpace(1);
pos.printText("**测试店铺");
pos.printLocation(0);
pos.printTextNewLine("----------------------------------------------");
pos.bold(false);
pos.printTextNewLine("订 单 号:1005199");
pos.printTextNewLine("用 户 名:15712937281");
pos.printTextNewLine("桌 号:3号桌");
pos.printTextNewLine("订单状态:订单已确认");
pos.printTextNewLine("订单日期:2016/2/19 12:34:53");
pos.printTextNewLine("付 款 人:线下支付(服务员:宝哥)");
pos.printTextNewLine("服 务 员:1001");
pos.printTextNewLine("订单备注:不要辣,少盐");
pos.printLine(2);
pos.printText("品项");
pos.printLocation(20, 1);
pos.printText("单价");
pos.printLocation(99, 1);
pos.printWordSpace(1);
pos.printText("数量");
pos.printWordSpace(3);
pos.printText("小计");
pos.printTextNewLine("----------------------------------------------");
for (FoodsBean foods : foodsBean) {
pos.printTextNewLine(foods.getName());
pos.printLocation(20, 1);
pos.printText(foods.getPrice());
pos.printLocation(99, 1);
pos.printWordSpace(1);
pos.printText(foods.getNumber());
pos.printWordSpace(3);
pos.printText(foods.getSum());
}
pos.printTextNewLine("----------------------------------------------");
pos.printLocation(1);
pos.printLine(2);
//打印二维码
pos.qrCode("http://blog.csdn.net/haovip123");
//切纸
pos.feedAndCut();
pos.closeIOAndSocket();
pos = null;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
});
}
private void initData() {
foodsBean = new ArrayList<>();
for (int i = 0; i < 4; i++) {
FoodsBean fb = new FoodsBean();
fb.setName("测试菜品" + i);
fb.setPrice("90.00");
fb.setNumber("1" + i);
fb.setSum("10" + i + ".00");
foodsBean.add(fb);
}
}
}
附:小票中菜品的Bean类
public class FoodsBean {
private String name;
private String price;
private String number;
private String sum;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getSum() {
return sum;
}
public void setSum(String sum) {
this.sum = sum;
}
}
打印小票样品如图:
小结:
对于调用打印机,不论使用Java语言还是其他语言,思路都是一样的,利用Socket连接上打印机以后,通过IO流进行输出打印,它们的打印指令都是一样的,可以下载打印手册,针对不同的设置,使用不同的打印指令即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# android
# 调用打印机
# esc
# pos
# Android实现PDF预览打印功能
# Android gradle插件打印时间戳的方法详解
# Android编程实现计算两个日期之间天数并打印所有日期的方法
# Android中如何安全地打印日志详解
# Mac 下 Android Studio 不打印日志的解决办法
# Android jni调试打印char阵列的实例详解
# Android下的POS打印机调用的简单实现
# Android 蓝牙连接 ESC/POS 热敏打印机打印实例(ESC/POS指令篇)
# Android 蓝牙连接 ESC/POS 热敏打印机打印实例(蓝牙连接篇)
# Android打印机--小票打印格式及模板设置实例代码
# Android手机通过蓝牙连接佳博打印机的实例代码
# Android实现系统打印功能
# 小票
# 流进
# 菜品
# 换行
# 台安
# 加粗
# 小计
# 端口号
# 打印工具
# 第一个
# 是一样的
# 要有
# 一台
# 写了
# 如图
# 来实现
# 装了
# 可以利用
# 可以下载
# 大家多多
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
黑客入侵网站服务器的常见手法有哪些?
Laravel如何使用.env文件管理环境变量?(最佳实践)
浅述节点的创建及常见功能的实现
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
个人摄影网站制作流程,摄影爱好者都去什么网站?
如何在阿里云完成域名注册与建站?
进行网站优化必须要坚持的四大原则
实例解析Array和String方法
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
网站制作免费,什么网站能看正片电影?
Laravel如何实现API版本控制_Laravel版本化API设计方案
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
EditPlus中的正则表达式实战(6)
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
昵图网官方站入口 昵图网素材图库官网入口
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
长沙做网站要多少钱,长沙国安网络怎么样?
Java类加载基本过程详细介绍
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
BootStrap整体框架之基础布局组件
Laravel中的withCount方法怎么高效统计关联模型数量
如何在建站之星网店版论坛获取技术支持?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
使用spring连接及操作mongodb3.0实例
JS去除重复并统计数量的实现方法
北京专业网站制作设计师招聘,北京白云观官方网站?
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
如何在万网自助建站平台快速创建网站?
如何打造高效商业网站?建站目的决定转化率
高端建站如何打造兼具美学与转化的品牌官网?
微信小程序 scroll-view组件实现列表页实例代码
三星、SK海力士获美批准:可向中国出口芯片制造设备
手机网站制作与建设方案,手机网站如何建设?
如何在万网主机上快速搭建网站?
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
C语言设计一个闪闪的圣诞树
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
linux top下的 minerd 木马清除方法
Laravel怎么使用Intervention Image库处理图片上传和缩放
如何快速启动建站代理加盟业务?
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
独立制作一个网站多少钱,建立网站需要花多少钱?
音响网站制作视频教程,隆霸音响官方网站?
如何在万网自助建站中设置域名及备案?

