android 控制POS機圖文打印(二)

上一篇文章結束了ESC/POS的指令集,沒看過的可以去看一下,可以當作工具文檔來使用的

android 控制POS機圖文打印(一)

這一篇正式介紹如何使用POS機來打印圖文信息。

首先介紹一下,ESC/POS指令是如何使用的,

字體加粗指令:

byte[] FONT_B = new byte[3];

FONT_B[0] = 27;

FONT_B[1] = 33;

FONT_B[2] = 8;

字體縱向放大一倍:

byte[] CLEAR_FONT = new byte[3];

CLEAR_FONT[0] = 0x1c;

CLEAR_FONT[1] = 0x21;

CLEAR_FONT[2] = 0;

清除字體放大指令:

byte[] FD_FONT = new byte[3];

FD_FONT[0] = 0x1c;

FD_FONT[1] = 0x21;

FD_FONT[2] = 4;

打印條形碼指令:

byte[] PRINT_CODE = new byte[9];

PRINT_CODE[0] = 0x1d;

PRINT_CODE[1] = 0x68;

PRINT_CODE[2] = 120;

PRINT_CODE[3] = 0x1d;

PRINT_CODE[4] = 0x48;

PRINT_CODE[5] = 0x10;

PRINT_CODE[6] = 0x1d;

PRINT_CODE[7] = 0x6B;

PRINT_CODE[8] = 0x02;

等等的指令使用。。。

可以參考下上一篇文章的指令集來進行設置。其中,ESC/POS指令是可以進行十進制和十六進制的設定的,這個大家要注意了。

接下來是介紹如何連接到打印機。

private static String PRINT_IP = "192.168.1.111";// 打印機IP地址

private static int PRINT_PORT = 9100;// 打印機端口 默認爲9100 建議不要修改打印機端口,修改了可能會連接不上的

這裏設定了打印機的IP地址和端口,其中,端口號爲9100是打印機默認的設置,最好就不要去修改,如果修改了,可能導致連接不上的,我一開始的時候設置了9000,就連接不上了。。。

然後就通過socket進行連接打印機

// 建立打印機連接

socket = new Socket();

InetSocketAddress iSocketAddress = new InetSocketAddress(PRINT_IP, PRINT_PORT);// 綁定打印機

socket.connect(iSocketAddress);// 建立連接

接下來就是寫一個打印的方法,調用打印機傳輸指令和數據到打印機進行打印。

直接上代碼了,代碼裏面的註釋得非常清楚

/**
	 * @param PRINT_DATA
	 *            小票主要數據
	 * @param GS_INFO
	 *            小票附帶信息
	 * @param CAIDAN_SN
	 *            小票號碼
	 */
	public void print(List<Map<String, Object>> PRINT_DATA,Map<String, String> GS_INFO, String CAIDAN_SN) {
		if (PRINT_DATA != null && PRINT_DATA.size() > 0) {
		try {
			// 條碼打印指令
			byte[] PRINT_CODE = new byte[9];
			PRINT_CODE[0] = 0x1d;
			PRINT_CODE[1] = 0x68;
			PRINT_CODE[2] = 120;
			PRINT_CODE[3] = 0x1d;
			PRINT_CODE[4] = 0x48;
			PRINT_CODE[5] = 0x10;
			PRINT_CODE[6] = 0x1d;
			PRINT_CODE[7] = 0x6B;
			PRINT_CODE[8] = 0x02;

			// 清除字體放大指令
			byte[] FD_FONT = new byte[3];
			FD_FONT[0] = 0x1c;
			FD_FONT[1] = 0x21;
			FD_FONT[2] = 4;
			
			// 字體加粗指令
			byte[] FONT_B = new byte[3];
			FONT_B[0] = 27;
			FONT_B[1] = 33;
			FONT_B[2] = 8;
			
			// 字體縱向放大一倍
			byte[] CLEAR_FONT = new byte[3];
			CLEAR_FONT[0] = 0x1c;
			CLEAR_FONT[1] = 0x21;
			CLEAR_FONT[2] = 0;
			
			// 計算合計金額
			int price = 0;
			
			// 初始化打印機
			socketOut.write(27);
			socketOut.write(64);
			socketOut.write(FD_FONT);// 字體放大
			socketOut.write(FONT_B);// 字體加粗
			socketOut.write(10);
			writer.write("  " + GS_INFO.get("GS_Name") + " \r\n");
			writer.flush();// 關鍵,很重要,不然指令一次性輸出,後面指令覆蓋前面指令,導致取消放大指令無效

			socketOut.write(CLEAR_FONT);
			socketOut.write(10);
			writer.write("NO: " + CAIDAN_SN + " \r\n");
			writer.write("------------------------------\r\n");
			writer.write("買家姓名: " + GS_INFO.get("GS_user_name") + "\r\n");
			writer.write("地址: " + GS_INFO.get("GS_address") + "\r\n");
			writer.write("聯繫電話: " + GS_INFO.get("GS_tel") + " \r\n");
			writer.write("付款方式: " + GS_INFO.get("GS_pay_type") + "\r\n");
			writer.write("------------------------------\r\n");
			writer.write(Fix_String_Lenth(1,Colum_Name[0], 4)
					+ Fix_String_Lenth(0,Colum_Name[1], 14)
					+ Fix_String_Lenth(1,Colum_Name[2], 4)
					+ Fix_String_Lenth(1,Colum_Name[3], 6) + "\r\n");
			for (int i = 0; i < PRINT_DATA.size() - 1; i++) {
				writer.write(Fix_String_Lenth(1,i + 1 + "", 2)
						+ Fix_String_Lenth(0,PRINT_DATA.get(i).get("cai_name").toString(), 14)
						+ Fix_String_Lenth(1,PRINT_DATA.get(i).get("cai_num").toString(), 4)
						+ Fix_String_Lenth(1,PRINT_DATA.get(i).get("cai_price").toString(), 6) + "\r\n");
				price += Double.parseDouble(PRINT_DATA.get(i).get("cai_price").toString());
			}
			
			// 打印二維碼
			Bitmap bmp = (Bitmap)PRINT_DATA.get(PRINT_DATA.size() - 1).get("erweima");
			
            byte[] data = new byte[] { 0x1B, 0x33, 0x00 };
            socketOut.write(data);
            data[0] = (byte)0x00;
            data[1] = (byte)0x00;
            data[2] = (byte)0x00;    //重置參數
            
            int pixelColor;
            
            // ESC * m nL nH 點陣圖
            byte[] escBmp = new byte[] { 0x1B, 0x2A, 0x00, 0x00, 0x00 };
            
            escBmp[2] = (byte)0x21;
            
            //nL, nH  
            escBmp[3] = (byte)(bmp.getWidth() % 256);
            escBmp[4] = (byte)(bmp.getWidth() / 256);
            
            // 每行進行打印
            for (int i = 0; i < bmp.getHeight()  / 24 + 1; i++){
            	socketOut.write(escBmp);
            	
                for (int j = 0; j < bmp.getWidth(); j++){
                    for (int k = 0; k < 24; k++){
                        if (((i * 24) + k) < bmp.getHeight()){
                            pixelColor = bmp.getPixel(j, (i * 24) + k);
                            if (pixelColor != -1){
                            	data[k / 8] += (byte)(128 >> (k % 8));
                            }
                        }
                    }
                    
                    socketOut.write(data);
                    // 重置參數
                    data[0] = (byte)0x00;
                    data[1] = (byte)0x00;
                    data[2] = (byte)0x00;
                }
                //換行
                byte[] byte_send1 = new byte[2];
                byte_send1[0] = 0x0d;
                byte_send1[1] = 0x0a;
                socketOut.write(byte_send1);
            }
            
            //換行
            byte[] byte_send2 = new byte[2];
            byte_send2[0] = 0x0d;
            byte_send2[1] = 0x0a;
            //發送測試信息 
            socketOut.write(byte_send2);
            
			writer.write("------------------------------\r\n");
			writer.write("本單共" + (PRINT_DATA.size() - 1) + "件商品,合計費用:" + price + "元\r\n");
			writer.write("------------------------------\r\n");
			writer.write("  謝 謝 惠 顧\r\n");
			// 下面指令爲打印完成後自動走紙
			writer.write(27);
			writer.write(100);
			writer.write(4);
			writer.write(10);
			writer.close();
			socketOut.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		}
	}
打印文字是傳輸String過去進行打印的,而需要打印圖片的話比較麻煩一下,需要把圖片轉換成點陣數據然後進行每行打印,可以參考print方法。

然後直接調用該方法就可以進行打印了,記住,android4.0之後不能在主線程中執行了,需要新建一個線程來執行該方法,如

new Thread() {
<span style="white-space:pre">	</span>public void run() {
<span style="white-space:pre">		</span>try {
<span style="white-space:pre">			</span>new PrintLine().print(lists, mapgs, sn);
<span style="white-space:pre">		</span>} catch (IOException e) {
<span style="white-space:pre">			</span>e.printStackTrace();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>};
}.start();
其實android調用pos機進行打印也不是想象中的那麼難搞的,只要把ESC/POS指令掌握了,如何傳輸指令和數據過去搞定了,就不難了,如果還需要其他操作,比如打印特殊符號,字體的其他效果的打印等等,都可以參考print方法中傳輸指令的方式進行設定,pos機就能識別到指令接收到數據進行打印了,是不是挺簡單的?有什麼問題大家可以一起討論的,本人也是初次接觸pos機的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章