Android进阶——安卓调用ESC/POS打印机打印实例
程序员文章站
2022-05-20 22:10:03
前言
前一段时间由于工作需要,要研究一下安卓程序调用打印机打印小票,并且要求不能使用蓝牙调用,研究了一下,可以利用socket连接,来实现打印功能。写了个demo,分...
前言
前一段时间由于工作需要,要研究一下安卓程序调用打印机打印小票,并且要求不能使用蓝牙调用,研究了一下,可以利用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流进行输出打印,它们的打印指令都是一样的,可以下载打印手册,针对不同的设置,使用不同的打印指令即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。