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

前言

前一段时间由于工作需要,要研究一下安卓程序调用打印机打印小票,并且要求不能使用蓝牙调用,研究了一下,可以利用socket连接,来实现打印功能。写了个Demo,分享一下。

工具:一台打印机(芯烨XP-80XX),一台安卓测试

开发环境:Android Studio 1.5

需求:点击按钮,实现打印小票功能,小票上除必要文字外,还要有二维码。

封装了一个Pos打印工具类:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.example.haoguibao.myapplication;  
  2.   
  3. import java.io.DataOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.OutputStream;  
  6. import java.io.OutputStreamWriter;  
  7. import java.net.Socket;  
  8.   
  9. /** 
  10.  * Created by haoguibao on 16/2/18. 
  11.  * Description : 封装Pos机打印工具类 
  12.  * Revision : 
  13.  */  
  14. public class Pos {  
  15.     //定义编码方式  
  16.     private static String encoding = null;  
  17.   
  18.     private Socket sock = null;  
  19.     // 通过socket流进行读写  
  20.     private OutputStream socketOut = null;  
  21.     private OutputStreamWriter writer = null;  
  22.   
  23.     /** 
  24.      * 初始化Pos实例 
  25.      * 
  26.      * @param ip 打印机IP 
  27.      * @param port  打印机端口号 
  28.      * @param encoding  编码 
  29.      * @throws IOException 
  30.      */  
  31.     public Pos(String ip, int port, String encoding) throws IOException {  
  32.         sock = new Socket(ip, port);  
  33.         socketOut = new DataOutputStream(sock.getOutputStream());  
  34.         this.encoding = encoding;  
  35.         writer = new OutputStreamWriter(socketOut, encoding);  
  36.     }  
  37.   
  38.     /** 
  39.      * 关闭IO流和Socket 
  40.      * 
  41.      * @throws IOException 
  42.      */  
  43.     protected void closeIOAndSocket() throws IOException {  
  44.         writer.close();  
  45.         socketOut.close();  
  46.         sock.close();  
  47.     }  
  48.   
  49.     /** 
  50.      * 打印二维码 
  51.      * 
  52.      * @param qrData 二维码的内容 
  53.      * @throws IOException 
  54.      */  
  55.     protected void qrCode(String qrData) throws IOException {  
  56.         int moduleSize = 8;  
  57.         int length = qrData.getBytes(encoding).length;  
  58.   
  59.         //打印二维码矩阵  
  60.         writer.write(0x1D);// init  
  61.         writer.write("(k");// adjust height of barcode  
  62.         writer.write(length + 3); // pl  
  63.         writer.write(0); // ph  
  64.         writer.write(49); // cn  
  65.         writer.write(80); // fn  
  66.         writer.write(48); //  
  67.         writer.write(qrData);  
  68.   
  69.         writer.write(0x1D);  
  70.         writer.write("(k");  
  71.         writer.write(3);  
  72.         writer.write(0);  
  73.         writer.write(49);  
  74.         writer.write(69);  
  75.         writer.write(48);  
  76.   
  77.         writer.write(0x1D);  
  78.         writer.write("(k");  
  79.         writer.write(3);  
  80.         writer.write(0);  
  81.         writer.write(49);  
  82.         writer.write(67);  
  83.         writer.write(moduleSize);  
  84.   
  85.         writer.write(0x1D);  
  86.         writer.write("(k");  
  87.         writer.write(3); // pl  
  88.         writer.write(0); // ph  
  89.         writer.write(49); // cn  
  90.         writer.write(81); // fn  
  91.         writer.write(48); // m  
  92.   
  93.         writer.flush();  
  94.   
  95.     }  
  96.   
  97.     /** 
  98.      * 进纸并全部切割 
  99.      * 
  100.      * @return 
  101.      * @throws IOException 
  102.      */  
  103.     protected void feedAndCut() throws IOException {  
  104.         writer.write(0x1D);  
  105.         writer.write(86);  
  106.         writer.write(65);  
  107.         //        writer.write(0);  
  108.         //切纸前走纸多少  
  109.         writer.write(100);  
  110.         writer.flush();  
  111.   
  112.         //另外一种切纸的方式  
  113.         //        byte[] bytes = {29, 86, 0};  
  114.         //        socketOut.write(bytes);  
  115.     }  
  116.   
  117.     /** 
  118.      * 打印换行 
  119.      * 
  120.      * @return length 需要打印的空行数 
  121.      * @throws IOException 
  122.      */  
  123.     protected void printLine(int lineNum) throws IOException {  
  124.         for (int i = 0; i < lineNum; i++) {  
  125.             writer.write("\n");  
  126.         }  
  127.         writer.flush();  
  128.     }  
  129.   
  130.     /** 
  131.      * 打印换行(只换一行) 
  132.      * 
  133.      * @throws IOException 
  134.      */  
  135.     protected void printLine() throws IOException {  
  136.         writer.write("\n");  
  137.         writer.flush();  
  138.     }  
  139.   
  140.     /** 
  141.      * 打印空白(一个Tab的位置,约4个汉字) 
  142.      * 
  143.      * @param length 需要打印空白的长度, 
  144.      * @throws IOException 
  145.      */  
  146.     protected void printTabSpace(int length) throws IOException {  
  147.         for (int i = 0; i < length; i++) {  
  148.             writer.write("\t");  
  149.         }  
  150.         writer.flush();  
  151.     }  
  152.   
  153.     /** 
  154.      * 打印空白(一个汉字的位置) 
  155.      * 
  156.      * @param length 需要打印空白的长度, 
  157.      * @throws IOException 
  158.      */  
  159.     protected void printWordSpace(int length) throws IOException {  
  160.         for (int i = 0; i < length; i++) {  
  161.             writer.write("  ");  
  162.         }  
  163.         writer.flush();  
  164.     }  
  165.   
  166.     /** 
  167.      * 打印位置调整 
  168.      * 
  169.      * @param position 打印位置  0:居左(默认) 1:居中 2:居右 
  170.      * @throws IOException 
  171.      */  
  172.     protected void printLocation(int position) throws IOException {  
  173.         writer.write(0x1B);  
  174.         writer.write(97);  
  175.         writer.write(position);  
  176.         writer.flush();  
  177.     }  
  178.   
  179.     /** 
  180.      * 绝对打印位置 
  181.      * 
  182.      * @throws IOException 
  183.      */  
  184.     protected void printLocation(int light, int weight) throws IOException {  
  185.         writer.write(0x1B);  
  186.         writer.write(0x24);  
  187.         writer.write(light);  
  188.         writer.write(weight);  
  189.         writer.flush();  
  190.     }  
  191.   
  192.     /** 
  193.      * 打印文字 
  194.      * 
  195.      * @param text 
  196.      * @throws IOException 
  197.      */  
  198.     protected void printText(String text) throws IOException {  
  199.         String s = text;  
  200.         byte[] content = s.getBytes("gbk");  
  201.         socketOut.write(content);  
  202.         socketOut.flush();  
  203.     }  
  204.   
  205.     /** 
  206.      * 新起一行,打印文字 
  207.      * 
  208.      * @param text 
  209.      * @throws IOException 
  210.      */  
  211.     protected void printTextNewLine(String text) throws IOException {  
  212.         //换行  
  213.         writer.write("\n");  
  214.         writer.flush();  
  215.   
  216.         String s = text;  
  217.         byte[] content = s.getBytes("gbk");  
  218.         socketOut.write(content);  
  219.         socketOut.flush();  
  220.     }  
  221.   
  222.     /** 
  223.      * 初始化打印机 
  224.      * 
  225.      * @throws IOException 
  226.      */  
  227.     protected void initPos() throws IOException {  
  228.         writer.write(0x1B);  
  229.         writer.write(0x40);  
  230.         writer.flush();  
  231.     }  
  232.   
  233.     /** 
  234.      * 加粗 
  235.      * 
  236.      * @param flag false为不加粗 
  237.      * @return 
  238.      * @throws IOException 
  239.      */  
  240.     protected void bold(boolean flag) throws IOException {  
  241.         if (flag) {  
  242.             //常规粗细  
  243.             writer.write(0x1B);  
  244.             writer.write(69);  
  245.             writer.write(0xF);  
  246.             writer.flush();  
  247.         } else {  
  248.             //加粗  
  249.             writer.write(0x1B);  
  250.             writer.write(69);  
  251.             writer.write(0);  
  252.             writer.flush();  
  253.         }  
  254.     }  
  255. }  
其中,打印机的IP和端口号从打印机的属性设置处可查。

MainActivity中进行调用:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.example.haoguibao.myapplication;  
  2.   
  3. import android.os.Bundle;  
  4. import android.support.v7.app.AppCompatActivity;  
  5. import android.view.View;  
  6. import android.widget.Button;  
  7.   
  8. import java.io.IOException;  
  9. import java.net.UnknownHostException;  
  10. import java.util.ArrayList;  
  11. import java.util.List;  
  12.   
  13. public class MainActivity extends AppCompatActivity {  
  14.     //订单菜品集合  
  15.     private List<FoodsBean> foodsBean;  
  16.   
  17.     private Pos pos;  
  18.   
  19.     @Override  
  20.     protected void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.activity_main);  
  23.   
  24.         Button bt_print = (Button) findViewById(R.id.button);  
  25.   
  26.   
  27.         bt_print.setOnClickListener(new View.OnClickListener() {  
  28.             @Override  
  29.             public void onClick(View v) {  
  30.   
  31.                 // 开启一个子线程  
  32.                 new Thread() {  
  33.                     public void run() {  
  34.                         try {  
  35.                             pos = new Pos("IP"9100"GBK");    //第一个参数是打印机网口IP  
  36.   
  37.                             //初始化打印机  
  38.                             pos.initPos();  
  39.   
  40.                             //初始化订单数据  
  41.                             initData();  
  42.   
  43.                             pos.bold(true);  
  44.                             pos.printTabSpace(2);  
  45.                             pos.printWordSpace(1);  
  46.                             pos.printText("**测试店铺");  
  47.   
  48.                             pos.printLocation(0);  
  49.                             pos.printTextNewLine("----------------------------------------------");  
  50.                             pos.bold(false);  
  51.                             pos.printTextNewLine("订 单 号:1005199");  
  52.                             pos.printTextNewLine("用 户 名:15712937281");  
  53.                             pos.printTextNewLine("桌    号:3号桌");  
  54.                             pos.printTextNewLine("订单状态:订单已确认");  
  55.                             pos.printTextNewLine("订单日期:2016/2/19 12:34:53");  
  56.                             pos.printTextNewLine("付 款 人:线下支付(服务员:宝哥)");  
  57.                             pos.printTextNewLine("服 务 员:1001");  
  58.                             pos.printTextNewLine("订单备注:不要辣,少盐");  
  59.                             pos.printLine(2);  
  60.   
  61.                             pos.printText("品项");  
  62.                             pos.printLocation(201);  
  63.                             pos.printText("单价");  
  64.                             pos.printLocation(991);  
  65.                             pos.printWordSpace(1);  
  66.                             pos.printText("数量");  
  67.                             pos.printWordSpace(3);  
  68.                             pos.printText("小计");  
  69.                             pos.printTextNewLine("----------------------------------------------");  
  70.   
  71.   
  72.                             for (FoodsBean foods : foodsBean) {  
  73.                                 pos.printTextNewLine(foods.getName());  
  74.                                 pos.printLocation(201);  
  75.                                 pos.printText(foods.getPrice());  
  76.                                 pos.printLocation(991);  
  77.                                 pos.printWordSpace(1);  
  78.                                 pos.printText(foods.getNumber());  
  79.                                 pos.printWordSpace(3);  
  80.                                 pos.printText(foods.getSum());  
  81.                             }  
  82.   
  83.                             pos.printTextNewLine("----------------------------------------------");  
  84.   
  85.                             pos.printLocation(1);  
  86.                             pos.printLine(2);  
  87.                             //打印二维码  
  88.                             pos.qrCode("http://blog.csdn.net/haovip123");  
  89.   
  90.                             //切纸  
  91.                             pos.feedAndCut();  
  92.   
  93.                             pos.closeIOAndSocket();  
  94.                             pos = null;  
  95.                         } catch (UnknownHostException e) {  
  96.                             e.printStackTrace();  
  97.                         } catch (IOException e) {  
  98.                             e.printStackTrace();  
  99.                         }  
  100.                     }  
  101.   
  102.                 }.start();  
  103.   
  104.             }  
  105.         });  
  106.     }  
  107.   
  108.     private void initData() {  
  109.         foodsBean = new ArrayList<>();  
  110.   
  111.         for (int i = 0; i < 4; i++) {  
  112.             FoodsBean fb = new FoodsBean();  
  113.             fb.setName("测试菜品" + i);  
  114.             fb.setPrice("90.00");  
  115.             fb.setNumber("1" + i);  
  116.             fb.setSum("10" + i + ".00");  
  117.             foodsBean.add(fb);  
  118.         }  
  119.     }  
  120. }  

附:小票中菜品的Bean类

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class FoodsBean {  
  2.     private String name;  
  3.     private String price;  
  4.     private String number;  
  5.     private String sum;  
  6.   
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.     public void setName(String name) {  
  11.         this.name = name;  
  12.     }  
  13.     public String getPrice() {  
  14.         return price;  
  15.     }  
  16.     public void setPrice(String price) {  
  17.         this.price = price;  
  18.     }  
  19.     public String getNumber() {  
  20.         return number;  
  21.     }  
  22.     public void setNumber(String number) {  
  23.         this.number = number;  
  24.     }  
  25.     public String getSum() {  
  26.         return sum;  
  27.     }  
  28.     public void setSum(String sum) {  
  29.         this.sum = sum;  
  30.     }  
  31. }  

打印小票样品如图:

        

小结:

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


某打印指令文档,仅供参考 : http://download.csdn.net/detail/haovip123/9702573 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值