欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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; 
  } 
} 

打印小票样品如图:

Android进阶——安卓调用ESC/POS打印机打印实例

小结:

对于调用打印机,不论使用java语言还是其他语言,思路都是一样的,利用socket连接上打印机以后,通过io流进行输出打印,它们的打印指令都是一样的,可以下载打印手册,针对不同的设置,使用不同的打印指令即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。