全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

前言

前一段时间由于工作需要,要研究一下安卓程序调用打印机打印小票,并且要求不能使用蓝牙调用,研究了一下,可以利用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实现系统打印功能  # 小票  # 流进  # 菜品  # 换行  # 台安  # 加粗  # 小计  # 端口号  # 打印工具  # 第一个  # 是一样的  # 要有  # 一台  # 写了  # 如图  # 来实现  # 装了  # 可以利用  # 可以下载  # 大家多多 


相关文章: 高防服务器租用如何选择配置与防御等级?  长沙做网站要多少钱,长沙国安网络怎么样?  如何制作网站标识牌,动态网站如何制作(教程)?  制作证书网站有哪些,全国城建培训中心证书查询官网?  山东网站制作公司有哪些,山东大源集团官网?  如何在服务器上配置二级域名建站?  建站之星后台密码遗忘或太弱?如何重置与强化?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  如何用虚拟主机快速搭建网站?详细步骤解析  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  测试制作网站有哪些,测试性取向的权威测试或者网站?  c# 在ASP.NET Core中管理和取消后台任务  建站之星免费版是否永久可用?  如何在Windows环境下新建FTP站点并设置权限?  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  定制建站方案优化指南:企业官网开发与建站费用解析  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  如何在宝塔面板中创建新站点?  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  定制建站如何定义?其核心优势是什么?  如何安全更换建站之星模板并保留数据?  如何选择香港主机高效搭建外贸独立站?  如何用景安虚拟主机手机版绑定域名建站?  C#怎么使用委托和事件 C# delegate与event编程方法  已有域名如何免费搭建网站?  网站企业制作流程,用什么语言做企业网站比较好?  建站之星展会模板:智能建站与自助搭建高效解决方案  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  建站之家VIP精选网站模板与SEO优化教程整合指南  高性能网站服务器配置指南:安全稳定与高效建站核心方案  如何零基础在云服务器搭建WordPress站点?  教育培训网站制作流程,请问edu教育网站的域名怎么申请?  定制建站流程解析:需求评估与SEO优化功能开发指南  广德云建站网站建设方案与建站流程优化指南  攀枝花网站建设,攀枝花营业执照网上怎么年审?  Android滚轮选择时间控件使用详解  实惠建站价格推荐:2025年高性价比自助建站套餐解析  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  如何用IIS7快速搭建并优化网站站点?  网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?  中山网站制作网页,中山新生登记系统登记流程?  如何快速搭建FTP站点实现文件共享?  岳西云建站教程与模板下载_一站式快速建站系统操作指南  视频网站app制作软件,有什么好的视频聊天网站或者软件?  如何通过PHP快速构建高效问答网站功能?  建站之星安装路径如何正确选择及配置?  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  如何快速搭建高效WAP手机网站吸引移动用户?  建站之星免费模板:自助建站系统与智能响应式一键生成 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。