Android連接網絡打印機進行打印
本文轉自:http://www.cnblogs.com/LIANQQ/p/4587637.html
做筆記
首先這是網絡打印工具類,通過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, "未能連接打印機");
}
}
}

