您好,登錄后才能下訂單哦!
前言
前一段時間由于工作需要,要研究一下安卓程序調用打印機打印小票,并且要求不能使用藍牙調用,研究了一下,可以利用socket連接,來實現打印功能。寫了個Demo,分享一下。
工具:一臺打印機(芯燁XP-80XX),一臺安卓測試機
開發(fā)環(huán)境: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) { //常規(guī)粗細 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("訂單狀態(tài):訂單已確認"); 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流進行輸出打印,它們的打印指令都是一樣的,可以下載打印手冊,針對不同的設置,使用不同的打印指令即可。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。