首先這是網絡打印工具類,通過Socket實現,多說一句,網絡打印機端口號一般默認的是9100
package com.Ieasy.Tool; import android.annotation.SuppressLint; import java.io.IOException ; import java.io.OutputStream ; import java.io.PrintWriter ; import java.net.InetSocketAddress ; import java.net.Socket ; import java.net.SocketAddress ; import java.nio.charset.Charset ; @SuppressLint("NewApi") public class NetPrinter { public Socket socket; public int POS_OPEN_NETPORT = 9100;// 0X238c public boolean IFOpen = false; public int Net_SendTimeout = 1000; public int Net_ReceiveTimeout = 1500; public String command = ""; //打印命令字符串 public byte[] outbytes; //傳輸的命令集 PrinterCMD pcmd = new PrinterCMD(); /// <summary> /// 網絡打印機 打開網絡打印機 /// </summary> /// <param name="ipaddress"></param> /// <returns></returns> public boolean Open(String ipaddress, int netport) { if (socket == null) { try { SocketAddress ipe = new InetSocketAddress(ipaddress,netport); socket = new Socket(); //Socket(ipaddress, netport,true); socket.connect(ipe); socket.setSoTimeout(Net_ReceiveTimeout); //socket.SendTimeout = Net_SendTimeout; IFOpen = true; //System.out.print("連接成功"); } catch(Exception e) { //MessageBox.Show("連接不成功"); e.printStackTrace(); IFOpen = false; } } else { try { socket.close(); SocketAddress ipe = new InetSocketAddress(ipaddress,netport); socket = new Socket(); //Socket(ipaddress, netport,true); socket.connect(ipe); socket.setSoTimeout(Net_ReceiveTimeout); //socket.SendTimeout = Net_SendTimeout; IFOpen = true; } catch(Exception e) { e.printStackTrace(); IFOpen = false; } } return IFOpen; } /// <summary> /// 網絡打印機 關閉 /// </summary> /// <param name="ipaddress"></param> /// <returns></returns> public void Close() { try { socket.close(); socket = null; } catch(Exception e) { e.printStackTrace(); } } /// <summary> /// 網絡打印機 初始化打印機 /// </summary> public void Set() { try { command = pcmd.CMD_SetPos(); OutputStream stream = socket.getOutputStream(); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /// <summary> /// 網絡打印機 打印的文本 /// </summary> /// <param name="pszString"></param> /// <param name="nFontAlign">0:居左 1:居中 2:居右</param> /// <param name="nfontsize">字體大小0:正常大小 1:兩倍高 2:兩倍寬 3:兩倍大小 4:三倍高 5:三倍寬 6:三倍大小 7:四倍高 8:四倍寬 9:四倍大小 10:五倍高 11:五倍寬 12:五倍大小</param> /// <param name="ifzhenda">0:非針打 1:針打</param> public void PrintText(String pszString, int nFontAlign, int nFontSize,int ifzhenda) { try { OutputStream stream = socket.getOutputStream(); command = pcmd.CMD_TextAlign(nFontAlign); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); if (ifzhenda == 1) { command = pcmd.CMD_FontSize_BTP_M280(nFontSize); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); command = pcmd.CMD_FontSize_BTP_M2801(nFontSize); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } else { command = pcmd.CMD_FontSize(nFontSize); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } command = pszString;// +CMD_Enter(); outbytes = command.getBytes(Charset.forName("GB2312")); //Charset.defaultCharset()); //forName("UTF-8") stream.write(outbytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return; } } /// <summary> /// 網絡打印機 回車 /// </summary> public void PrintEnter() { try { command = pcmd.CMD_Enter(); OutputStream stream = socket.getOutputStream(); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /// <summary> /// 網絡打印機 切割 /// </summary> /// <param name="pagenum">切割時,走紙行數</param> public void CutPage(int pagenum) { try { OutputStream stream = socket.getOutputStream(); command = pcmd.CMD_PageGO(pagenum) + pcmd.CMD_Enter(); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); command = pcmd.CMD_CutPage() + pcmd.CMD_Enter(); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /// <summary> /// 網絡打印機換行 /// </summary> /// <param name="lines"></param> public void PrintNewLines(int lines) { try { OutputStream stream = socket.getOutputStream(); command = pcmd.CMD_FontSize(0); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); for (int i = 0; i < lines; i++) { command = "" + pcmd.CMD_Enter(); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /// <summary> /// 打開錢箱 /// </summary> public void OpenQianXiang() { try { OutputStream stream = socket.getOutputStream(); command = "" + pcmd.CMC_QianXiang(); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /// <summary> /// 打印條碼 /// </summary> /// <param name="numstr"></param> /// <param name="height"></param> /// <param name="width"></param> /// <param name="numweizi">1:上方 2:下方 0:不打印數字</param> /// <param name="fontalign">0:居左 1:居中 2:居右</param> /// <param name="fontsize">字體大小0:正常大小 1:兩倍高 2:兩倍寬 3:兩倍大小 4:三倍高 5:三倍寬 6:三倍大小 7:四倍高 8:四倍寬 9:四倍大小 10:五倍高 11:五倍寬 12:五倍大小</param> public void PrintTiaoMa(String numstr, int height, int width, int numweizi, int fontalign, int fontsize) { try { OutputStream stream = socket.getOutputStream(); command = pcmd.CMD_TiaoMaHeight(height); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); command = pcmd.CMD_TiaoMaWidth(width); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); command = pcmd.CMD_TiaoMaWeiZi(numweizi); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); command = pcmd.CMD_TextAlign(fontalign); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); command = pcmd.CMD_FontSize(fontsize); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); command = pcmd.CMD_TiaoMaPrint(numstr); outbytes = command.getBytes(Charset.forName("ASCII")); stream.write(outbytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class PrinterCMD { /// <summary> /// 初始化打印機 /// </summary> /// <returns></returns> public String CMD_SetPos() { return new StringBuffer().append((char)27).append((char)64).toString(); } /// <summary> /// 換行(回車) /// </summary> /// <returns></returns> public String CMD_Enter() { return new StringBuffer().append((char)10).toString(); } /// <summary> /// 對齊模式 /// </summary> /// <param name="align">0:左對齊 1:中對齊 2:右對齊</param> /// <returns></returns> public String CMD_TextAlign(int align) { return new StringBuffer().append((char)27).append((char)97).append((char)align).toString(); } /// <summary> /// 字體的大小 /// </summary> /// <param name="nfontsize">0:正常大小 1:兩倍高 2:兩倍寬 3:兩倍大小 4:三倍高 5:三倍寬 6:三倍大小 7:四倍高 8:四倍寬 9:四倍大小 10:五倍高 11:五倍寬 12:五倍大小</param> /// <returns></returns> public String CMD_FontSize(int nfontsize) { String _cmdstr = ""; //設置字體大小 switch (nfontsize) { case -1: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)0).toString();//29 33 break; case 0: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)0).toString();//29 33 break; case 1: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)1).toString(); break; case 2: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)16).toString(); break; case 3: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)17).toString(); break; case 4: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)2).toString(); break; case 5: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)32).toString(); break; case 6: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)34).toString(); break; case 7: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)3).toString(); break; case 8: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)48).toString(); break; case 9: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)51).toString(); break; case 10: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)4).toString(); break; case 11: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)64).toString(); break; case 12: _cmdstr = new StringBuffer().append((char)29).append((char)33).append((char)68).toString(); break; } return _cmdstr; } /// <summary> /// BTP-M280(針打) 倍寬倍高 /// </summary> /// <param name="size">0:取消倍寬倍高模式 1:倍高模式 2:倍寬模式 3:兩倍大小</param> /// <returns></returns> public String CMD_FontSize_BTP_M280(int size) { String _cmdstr = ""; //只有0和1兩種模式 int fontsize = size; switch (fontsize) { case 1: _cmdstr = new StringBuffer().append((char)28).append((char)33).append((char)8).toString(); break; case 2: _cmdstr = new StringBuffer().append((char)28).append((char)33).append((char)4).toString(); break; case 3: _cmdstr = new StringBuffer().append((char)28).append((char)87).append((char)1).toString(); break; default: _cmdstr = new StringBuffer().append((char)28).append((char)87).append((char)0).toString(); break; } return _cmdstr; } /// <summary> /// BTP-M280(針打) 倍寬倍高 /// </summary> /// <param name="size">0:取消倍寬倍高模式 1:倍高模式 2:倍寬模式 3:兩倍大小</param> /// <returns></returns> public String CMD_FontSize_BTP_M2801(int size) { String _cmdstr = ""; //只有0和1兩種模式 int fontsize = size; switch (fontsize) { case 1: _cmdstr = new StringBuffer().append((char)27).append((char)33).append((char)17).toString(); break; case 2: _cmdstr = new StringBuffer().append((char)27).append((char)33).append((char)33).toString(); break; case 3: _cmdstr = new StringBuffer().append((char)27).append((char)33).append((char)49).toString(); break; default: _cmdstr = new StringBuffer().append((char)27).append((char)33).append((char)1).toString(); break; } return _cmdstr; } /// <summary> /// 走紙 /// </summary> /// <param name="line">走紙的行數</param> /// <returns></returns> public String CMD_PageGO(int line) { return new StringBuffer().append((char)27).append((char)100).append((char)line).toString(); } /// <summary> /// 切割 /// </summary> /// <returns></returns> public String CMD_CutPage() { return new StringBuffer().append((char)27).append((char)109).toString(); } /// <summary> /// 返回狀態(返回8位的二進制) /// </summary> /// <param name="num">1:打印機狀態 2:脫機狀態 3:錯誤狀態 4:傳送紙狀態</param> /// 返回打印機狀態如下: /// 第一位:固定為0 /// 第二位:固定為1 /// 第三位:0:一個或兩個錢箱打開 1:兩個錢箱都關閉 /// 第四位:0:聯機 1:脫機 /// 第五位:固定為1 /// 第六位:未定義 /// 第七位:未定義 /// 第八位:固定為0 /// /// 返回脫機狀態如下: /// 第一位:固定為0 /// 第二位:固定為1 /// 第三位:0:上蓋關 1:上蓋開 /// 第四位:0:未按走紙鍵 1:按下走紙鍵 /// 第五位:固定為1 /// 第六位:0:打印機不缺紙 1: 打印機缺紙 /// 第七位:0:沒有出錯情況 1:有錯誤情況 /// 第八位:固定為0 /// /// 返回錯誤狀態如下: /// 第一位:固定為0 /// 第二位:固定為1 /// 第三位:未定義 /// 第四位:0:切刀無錯誤 1:切刀有錯誤 /// 第五位:固定為1 /// 第六位:0:無不可恢復錯誤 1: 有不可恢復錯誤 /// 第七位:0:打印頭溫度和電壓正常 1:打印頭溫度或電壓超出范圍 /// 第八位:固定為0 /// /// 返回傳送紙狀態如下: /// 第一位:固定為0 /// 第二位:固定為1 /// 第三位:0:有紙 1:紙將盡 /// 第四位:0:有紙 1:紙將盡 /// 第五位:固定為1 /// 第六位:0:有紙 1:紙盡 /// 第七位:0:有紙 1:紙盡 /// 第八位:固定為0 /// <returns></returns> public String CMD_ReturnStatus(int num) { return new StringBuffer().append((char)16).append((char)4).append((char)num).toString(); } /// <summary> /// 條碼高寬 /// </summary> /// <param name="num"></param> /// <returns></returns> public String CMD_TiaoMaHeight(int num) { //return ((char)29).append"h" + ((char)num).toString(); return new StringBuffer().append((char)29).append((char)104).append((char)num).toString(); } /// <summary> /// 條碼寬度 /// </summary> /// <param name="num"></param> /// <returns></returns> public String CMD_TiaoMaWidth(int num) { //return ((char)29).append"w" + ((char)num).toString(); return new StringBuffer().append((char)29).append((char)119).append((char)num).toString(); } /// <summary> /// 條碼數字打印的位置 /// </summary> /// <param name="num">1:上方 2:下方 0:不打印數字</param> /// <returns></returns> public String CMD_TiaoMaWeiZi(int num) { return new StringBuffer().append((char)29).append("H").append((char)num).toString(); } /// <summary> /// 開始打印(條碼類型為CODE39) /// </summary> /// <param name="numstr"></param> /// <returns></returns> public String CMD_TiaoMaPrint(String numstr) { //return ((char)29).append"k" + ((char)4).appendnumstr + ((char)0).toString(); return new StringBuffer().append((char)29).append((char)107).append((char)4).append(numstr).append ((char)0).toString(); } /// <summary> /// 打開錢箱 /// </summary> /// <returns></returns> public String CMC_QianXiang() { return new StringBuffer().append((char)27).append((char)112).append((char)0).append((char)60).append((char)255).toString(); } }
具體怎么調用,每個方法注釋寫得都很清楚了,至於怎么排版,要看紙的寬度了,然后自己計算字符的長度進行設置,下面是一個異步調用的例子,下面方法僅僅是一個例子,請無視其他無用代碼。
頁面排版實現,首先得知道打印紙的寬度,還有你要在紙上顯示幾列,譬如我這個方法 我顯示了4列,所有我先根據打印紙的寬度 先設置好每一列的大致寬度,如果該列的字符長度大於設置好的 可以設置換行,如果小於,為了排版整齊 可以補空格,大致實現原理就是這樣。
// 粗略計算打印紙上每個字段占的長度 private int wlname = 18; private int wlnum = 6; private int wlunit = 7; private int wlprice = 9;
/** * 網絡打印機 * * */ class NetPrint extends AsyncTask<String, String, String> { private String LocalYHID; private List<SaveEnity> ListWz = new ArrayList<SaveEnity>(); private String Rr = ""; private String GysName = ""; private String title = ""; private String printtime = ""; private String errInfo = ""; private String TotlePrice = ""; private NetPrinter printer; private String Md_Name; private String Date_Time; public NetPrint(String LocalYHID, String GysName,String Date_Time) { this.LocalYHID = LocalYHID; this.GysName = GysName; this.Date_Time = Date_Time; isclick = true; } @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub try { printer = new NetPrinter(); if(!Utils.isEmpty(Const.print_Port)){ printer.Open(Const.print_IP, Integer.parseInt(Const.print_Port)); } if(printer.IFOpen){ JSONArray ArrayItems = new JSONArray(); ArrayItems = usedatabase.getLocalData(LocalYHID); TotlePrice = usedatabase.getTotlePrice(LocalYHID); ListWz = JSON.parseArray(ArrayItems.toString(), SaveEnity.class); MyLogger.showLogWithLineNum(5, ListWz.size() + "長度"); Collections.sort(ListWz, new SaComParator()); List<String> Select = new ArrayList<String>(); List<String> EndSelect = new ArrayList<String>(); for (int i = 0; i < ListWz.size(); i++) { SaveEnity save = ListWz.get(i); Select.add(save.DJX_CK_NAME); } for (String s : Select) { if (Collections.frequency(EndSelect, s) < 1) EndSelect.add(s); } for (int i = 0; i < EndSelect.size(); i++) { Rr += formatSSTest(EndSelect.get(i), ListWz); } String Name = "物料名"; String Num = "數量"; String Unit = "單位"; String Price = "單價"; String Spc = ""; for (int j = 0; j < wlname - getWordCount("物料名"); j++) { Spc = Spc + " "; } Log.e("物料名稱長度"+wlname+"補空格", wlname-getWordCount("物料名")+""); Name = Name + Spc; Spc = ""; for (int i = 0; i < wlnum - getWordCount("數量"); i++) { Spc = Spc + " "; } Num = Spc + Num; Log.e("數量長度"+wlnum+"補空格", wlnum-getWordCount("數量")+""); Spc = ""; for (int i = 0; i < wlunit - getWordCount("單位"); i++) { Spc = Spc + " "; } Unit = Spc + Unit; Spc = ""; Log.e("單位長度"+wlunit+"補空格", wlunit-getWordCount("單位")+""); for (int i = 0; i < wlprice - getWordCount("單價"); i++) { Spc = Spc + " "; } Price = Spc + Price; Spc = ""; Log.e("長度"+wlprice+"補空格", wlprice-getWordCount("單價")+""); String printstr = Name + Price + Num + Unit; title = "供應商: " + GysName + "\n" + printstr; printtime = "打印時間:" + Date_Time + "\n\n"; Md_Name = Const.MD_Name; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); } @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub super.onPostExecute(result); if(printer.IFOpen){ String[] aaray = Rr.split("#"); printer.PrintText(title, 0, 0, 0); printer.PrintEnter(); for (String s : aaray) { printer.PrintText(s, 0, 0, 0); } printer.PrintEnter(); printer.PrintText(TotlePrice, 0, 0, 0); printer.PrintEnter(); printer.PrintEnter(); printer.PrintText(printtime, 0, 0, 0); printer.PrintEnter(); printer.PrintText(Md_Name, 1,1,0); printer.PrintNewLines(5); printer.CutPage(0); printer.Close(); isclick = false; MyToast.MyLogo(History.this, "打印完成"); }else{ MyToast.MyLogo(History.this, "未能連接打印機"); } } }