EscPos 小票打印機(jī)模板設(shè)計(jì)

https://github.com/SubLuLu/thermal_printer

小票打印機(jī)缴渊, 目前主要有這么幾個(gè)寬度規(guī)格 58mm 70mm 80mm覆获,常見(jiàn)的58mm和80mm為用得比較多帆赢, 對(duì)于模板的設(shè)計(jì)來(lái)說(shuō)下硕,其中的區(qū)別基本上只在于每行可以顯示多少個(gè)字符。58mm的小票熱敏紙羽资,一行最大可以顯示32個(gè)半角字符淘菩,而80mm的則可以顯示48個(gè)半角字符。

EscPos 為目前主流小票打印機(jī)都支持的一種打印機(jī)控制命令集, 而其很重要的一個(gè)特點(diǎn)是無(wú)需驅(qū)動(dòng)支持潮改。 有以下兩種方式可以向一臺(tái)打印機(jī)發(fā)送這種命令狭郑。

  1. USB連接的情況下,直接向 LPT1 這個(gè)設(shè)備寫(xiě)入命令(或者COM口)汇在。在windows下翰萨,外接設(shè)備被映射到系統(tǒng)中,其實(shí)也有其自己的路徑糕殉, 不過(guò)這個(gè)路徑和一般的文件路徑不一樣罷了亩鬼, 如果從Linux的/dev/sda0 => /mnt/sda0 這樣來(lái)理解可能會(huì)好理解點(diǎn)。那么使用CreateFile(設(shè)備路徑), 獲取一個(gè)緩沖區(qū)地址阿蝶,然后往這個(gè)緩沖區(qū)寫(xiě)入數(shù)據(jù)雳锋,數(shù)據(jù)就會(huì)被發(fā)送到設(shè)備,以實(shí)現(xiàn)通訊

  2. 網(wǎng)線連接羡洁。一般的小票打印機(jī)都可以插網(wǎng)線玷过,同時(shí)開(kāi)放了9100這個(gè)端口, 可以通過(guò)socket建立連接筑煮,向這個(gè)端口發(fā)送數(shù)據(jù)冶匹,也同樣可以和設(shè)備建立通訊連接


以上為一些基本,接下來(lái)分享如何設(shè)計(jì)模板咆瘟。

由于小票的適用范圍, 其實(shí)可以歸結(jié)為以下幾點(diǎn):

  1. 小票可以看作是一行一行的字符拼接成完整的小票诽里, 按照布局上來(lái)說(shuō)袒餐, 那么就像是一個(gè)只有一欄的表格, 只要決定了每一行是什么樣子谤狡, 整體的樣子就有了

  2. 由于小票一般都不是很寬灸眼,那么一個(gè)字符或者一個(gè)字符串在當(dāng)前行的某個(gè)具體位置并不重要,只需要 居左 居中 居右 三種位置屬性即可墓懂,即使有焰宣, 橫向的布局也應(yīng)該是橫向的填充布局

  3. 小票不需要很多很花的樣式

。捕仔。匕积。

基于以上幾點(diǎn), 將小票分為三個(gè)部分

頭的部分榜跌,主要顯示標(biāo)題闪唆、打印時(shí)間、單號(hào)等信息
體的部分钓葫,主要顯示項(xiàng)目明細(xì)悄蕾,從一個(gè)List里按順序輸出每行即可
尾的部分,一些其他內(nèi)容础浮,可以是文本帆调,可以是鏈接

按照上面github的這個(gè)庫(kù)里所說(shuō)奠骄, 把內(nèi)容類型分為 文本 條形碼 二維碼 和圖片,黑白的情況下番刊,圖片并不是很有必要

"header": [
        {
            "text": "{$shopname}",
            "size": 2,
            "bold": true,
            "format": 1,
            "line": 2,
            "underline": true,
            "type": 0
        },
    ]

以一個(gè)json數(shù)組存儲(chǔ)頭的部分內(nèi)容含鳞,不同的類型的內(nèi)容擁有不同的屬性,最關(guān)鍵的是占位符撵枢,{$shopname} 這樣的字符 可以使用 \{\$(.+?)\} 這個(gè)正則來(lái)匹配民晒, 匹配到之后,根據(jù)每個(gè)占位符的內(nèi)容不同锄禽,替換成不同的實(shí)際數(shù)據(jù)潜必,如果不使用占位符,也可以直接填入完整的數(shù)據(jù)沃但。這個(gè)數(shù)組里的元素磁滚,會(huì)按照順序一行一行地打印出來(lái),即這個(gè)數(shù)組里每個(gè)json對(duì)象都代表著一行宵晚。

"goods": [
        {
            "name": "商品名",
            "width": 24,
            "format": 0,
            "variable": "name"
        }
    ],

這里的每一個(gè)對(duì)象垂攘, 表示的是明細(xì)部分的一列, 標(biāo)識(shí)出了列名淤刃,列寬晒他,列標(biāo)題的位置,還有一個(gè)則是表示該列的數(shù)據(jù)存取的字段名逸贾,例如后面拿到了name的數(shù)據(jù)陨仅,那么去這個(gè)模板里查找,來(lái)指定其格式和位置

    "bill": [
        {
            "text": "實(shí)收現(xiàn)金",
            "size": 3,
            "bold": true,
            "format": 1,
            "line": 2,
            "underline": false,
            "type": 0
        },
        {
            "text": "{$cash}",
            "size": 3,
            "bold": true,
            "format": 1,
            "line": 2,
            "underline": false,
            "type": 0
        }
    ],

這里的結(jié)構(gòu)和header還有footer的是一樣的铝侵,你當(dāng)然也可以加入其他類型的內(nèi)容灼伤,比如adv 廣告什么的。

模板的解析咪鲜,對(duì)于java等語(yǔ)言來(lái)說(shuō)很是簡(jiǎn)單狐赡,因?yàn)樗麄兌加袆?dòng)態(tài)類型這樣的東西。但是對(duì)于Delphi來(lái)說(shuō)疟丙,TObject如果不在TJson.JsonToObject的時(shí)候指定其類型颖侄,那么反序列化是沒(méi)用的。不過(guò)可以使用TJsonObject或者TJsonArray來(lái)替代享郊,對(duì)于動(dòng)態(tài)的json发皿,就不能像其他語(yǔ)言那么方便地直接操作對(duì)象了,用TJsonObject的方法來(lái)替代即可拂蝎。
例如穴墅, goods的子對(duì)象里有一個(gè)type字段,根據(jù)這個(gè)字段,可以判斷出當(dāng)前這個(gè)對(duì)象的類型玄货,有了具體的類型皇钞,

if goods[i].GetValue<Integer>('type') =0 then
begin
    thegoods := TJson.JsonToObject<TText>(goods[i].ToJson());
end;

這樣就可以獲得具體的實(shí)例了.

最后,也是關(guān)鍵的一步就是打印了松捉,當(dāng)把整個(gè)模板轉(zhuǎn)換為一行行的字符串之后夹界,不能直接發(fā)送。首先是需要異步發(fā)送隘世, 否則阻塞主線程必然不是個(gè)好實(shí)踐可柿,然后,每個(gè)字符串需要按順序發(fā)送丙者。

那么需要一個(gè)有序的隊(duì)列來(lái)處理整個(gè)發(fā)送复斥。Delphi自帶的TQueue是個(gè)好的選擇,不過(guò)由于其存儲(chǔ)的是指針械媒,那么可以對(duì)其進(jìn)行一層封裝目锭,例如把一個(gè)包含每一行字符串的 Record的地址Push入隊(duì)列,這里需要注意纷捞,每次Push需要 New(TPrintObj), 否則最終隊(duì)列中都是同樣的內(nèi)容了痢虹。

另外還有幾個(gè)隊(duì)列可以選擇

http://blog.sina.com.cn/s/blog_722bc92e0101gngd.html
這個(gè)隊(duì)列據(jù)說(shuō)很快

DIOCP v5中有一個(gè)TSafeQueue,也比較看好

還有一個(gè)

http://blog.qdac.cc/?p=148
無(wú)鎖隊(duì)列也可以進(jìn)行嘗試主儡。

當(dāng)然了奖唯,一味追求效率沒(méi)有必要,那一點(diǎn)點(diǎn)時(shí)間的提升糜值,不如拿來(lái)保證整個(gè)服務(wù)的穩(wěn)定

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末臭埋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子臀玄,更是在濱河造成了極大的恐慌,老刑警劉巖畅蹂,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件健无,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡液斜,警方通過(guò)查閱死者的電腦和手機(jī)累贤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)少漆,“玉大人臼膏,你說(shuō)我怎么就攤上這事∈舅穑” “怎么了渗磅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我始鱼,道長(zhǎng)仔掸,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任医清,我火速辦了婚禮起暮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘会烙。我一直安慰自己负懦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布柏腻。 她就那樣靜靜地躺著纸厉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葫盼。 梳的紋絲不亂的頭發(fā)上残腌,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音贫导,去河邊找鬼抛猫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛孩灯,可吹牛的內(nèi)容都是我干的闺金。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼峰档,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼败匹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起讥巡,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤掀亩,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后欢顷,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體槽棍,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年抬驴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了炼七。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡布持,死狀恐怖豌拙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情题暖,我是刑警寧澤按傅,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布捉超,位于F島的核電站,受9級(jí)特大地震影響逞敷,放射性物質(zhì)發(fā)生泄漏狂秦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一推捐、第九天 我趴在偏房一處隱蔽的房頂上張望裂问。 院中可真熱鬧,春花似錦牛柒、人聲如沸堪簿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)椭更。三九已至,卻和暖如春蛾魄,著一層夾襖步出監(jiān)牢的瞬間虑瀑,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工滴须, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舌狗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓扔水,卻偏偏與公主長(zhǎng)得像痛侍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子魔市,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 激光技術(shù)出現(xiàn)于60年代主届,真正投入實(shí)際應(yīng)用始于70年代初期。最早的激光發(fā)射器是充有氦-氖(He-Ne)氣體的電子激...
    我是嘻哈大哥閱讀 3,035評(píng)論 1 6
  • 最近競(jìng)品公司出了一個(gè)接入藍(lán)牙打印機(jī)的功能待德,作為競(jìng)爭(zhēng)對(duì)手公司肯定不能少所以就給我分了任務(wù)君丁,搞定藍(lán)牙打印機(jī) 首先介紹一...
    呆北默閱讀 3,254評(píng)論 12 10
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)将宪,斷路器绘闷,智...
    卡卡羅2017閱讀 134,633評(píng)論 18 139
  • 上一篇 主要介紹了如何通過(guò)藍(lán)牙連接到打印機(jī)。這一篇毙死,我們就介紹如何向打印機(jī)發(fā)送打印指令燎潮,來(lái)打印字符和圖片。 ===...
    VitaminChen閱讀 52,522評(píng)論 90 159
  • 夜色茫茫扼倘, 漫步海邊确封。 秋寒如水除呵, 海風(fēng)陣陣。 沙灘靜臥爪喘, 大地滄桑颜曾。 凝望大海, 默然無(wú)言秉剑。 天之盡頭泛豪, 路之遙...
    悠然芬芳閱讀 353評(píng)論 0 5