首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS Socket 連接局域網 POS 打印機:ESC/POS 指令集與打印格式自定義實戰

     編輯:程式設計綜合問答

核心架構

iOS App → **TCP Socket** → 局域網 POS 打印機 (IP:Port) → **ESC/POS 指令流** → 打印輸出。

關鍵步驟

1. Socket 連接 (Swift / Objective-C)


// Swift - 使用 NWConnection (Network 框架, iOS 12+)
import Network

let host = NWEndpoint.Host("192.168.1.100")
let port = NWEndpoint.Port(9100) // 常見端口
let connection = NWConnection(host: host, port: port, using: .tcp)

connection.stateUpdateHandler = { state in
    switch state {
    case .ready: print("已連接"); sendPrintData(connection)
    case .failed(let err): print("連接失敗: \(err)")
    default: break
    }
}
connection.start(queue: .global())

2. ESC/POS 指令構建 (核心:格式自定義)

打印機不識別 HTML/CSS,**只識別 ESC/POS 二進制指令**。常用指令:

功能指令 (十六進制)說明
初始化`1B 40`ESC @ - 重置打印機
對齊`1B 61 n`ESC a - n=0左,1中,2右
字體放大`1D 21 n`GS ! - n=高4位寬放大,低4位高放大 (如 0x11=雙高雙寬)
粗體`1B 45 1` / `1B 45 0`ESC E - 開/關
換行`0A`LF
切紙`1D 56 00` / `1D 56 01`GS V - 全切/半切
打印文本文本內容字節 (UTF-8/GBK)需確認打印機編碼模式
打印圖片`1D 76 30 00` + 圖片數據GS v 0 - 光柵圖片打印 (較複雜)
設置行間距`1B 33 n`ESC 3 - n=點數 (默認30)

3. 發送數據示例 (Swift)


func sendPrintData(_ connection: NWConnection) {
    var commands = [UInt8]()
    
    // 初始化
    commands += [0x1B, 0x40]
    
    // 標題:居中、雙高雙寬、粗體
    commands += [0x1B, 0x61, 0x01]          // 居中
    commands += [0x1D, 0x21, 0x11]          // 雙高雙寬
    commands += [0x1B, 0x45, 0x01]          // 粗體開
    let title = "訂單詳情\n".data(using: .utf8)! // 或 GBK
    commands += title
    commands += [0x1B, 0x45, 0x00]          // 粗體關
    commands += [0x1D, 0x21, 0x00]          // 恢復正常大小
    commands += [0x0A]                      // 換行
    
    // 內容:左對齊、正常字體
    commands += [0x1B, 0x61, 0x00]          // 左對齊
    let items = "商品A x 1  ¥10.00\n商品B x 2  ¥20.00\n".data(using: .utf8)!
    commands += items
    commands += [0x0A]
    
    // 總計:右對齊、加粗
    commands += [0x1B, 0x61, 0x02]          // 右對齊
    commands += [0x1B, 0x45, 0x01]
    let total = "總計: ¥50.00\n".data(using: .utf8)!
    commands += total
    commands += [0x1B, 0x45, 0x00]
    
    // 切紙
    commands += [0x1D, 0x56, 0x00]
    
    // 發送
    let data = Data(commands)
    connection.send(content: data, completion: .contentProcessed { err in
        if let err = err { print("發送失敗: \(err)") }
        else { print("發送完成"); connection.cancel() }
    })
}

4. 編碼問題 (關鍵坑)

  • 多數國產打印機默認 **GBK/GB2312**,部分支持 UTF-8 (需發送指令切換 `1B 74 03` 選字符集)。
  • **建議**:發送前將字符串轉 `GBK` Data:`str.data(using: String.Encoding(rawValue: CFStringConvertEncodingToNSStringEncoding(0x0632)))` (CoreFoundation GBK 編碼)。

5. 斷線重連與狀態監聽


connection.stateUpdateHandler = { state in
    switch state {
    case .waiting(let err): 
        // 等待網絡恢復,可延遲重試
        DispatchQueue.global().asyncAfter(deadline: .now() + 5) { 
            connection.restart() 
        }
    case .cancelled: break
    default: break
    }
}

進階:封裝 PrintManager 單例


class PrintManager {
    static let shared = PrintManager()
    private var connection: NWConnection?
    
    func connect(ip: String, port: UInt16, completion: @escaping (Bool) -> Void) {
        // ... 建立連接 ...
    }
    
    func printOrder(_ order: Order) {
        // 構建 ESC/POS 數據 ...
        send(data)
    }
    
    private func send(_ data: Data) {
        connection?.send(content: data, completion: .contentProcessed { _ in })
    }
}

總結

**Socket 只是傳輸管道,格式自定義全靠 ESC/POS 指令**。掌握**「初始化 → 字體/對齊/屬性設置 → 發送文本/圖片數據 → 切紙」**指令流構建模式,配合**編碼轉換 (GBK/UTF-8)**、**斷線重連**、**封裝管理類**,即可實現靈活、穩定的 POS 打印功能。參考文檔:打印機廠商提供的《ESC/POS 指令編程手冊》。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved