天天看點

C#控制DataMax列印機問題總結

最近兩周時間一直在測試系統涉及條碼列印問題,由于原來系統采用通用驅動方式統一Intermac/ZeBar/DataMAx列印.但在處理DataMax列印效果是出現列印條碼出現鋸齒散射狀,導緻掃描槍無法識别.

我拿到列印機型号DataMax-I-4208熱敏列印型号,坦白說解決問題過程是很折磨人的,一方面源自這方面官方提供資源和列印執行個體有限,另外一方面設計到裝置參數具體調試, 針對C#控制DataMax-I-4208一系列問題解決方法作如下總結:

<1>DataMax列印Code128條碼出現鋸齒狀

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134210422.jpg"></a>

DataMax列印機型号:DataMax-I-4208-203DPI

當我們在預設情況下把系統生成的條碼BMP格式圖檔通過驅動方式發給列印機.采用DPI是目前本地系統螢幕預設顯示的DPI值一般是96DPI. 這樣導緻列印機值不一緻出現就 鋸齒 模糊列印效果: C#中如何設定修改DPI:

//設定DPI決定屬性值與DataMAx必須相符203DPI 必須一緻     

var setdpiimg = (Bitmap)_DrawImg;     

if (setdpiimg != null)     

   {     

       setdpiimg.SetResolution(203f, 203f);     

   } 

DPI是每英寸點數, 如果DPI的值過低,則圖檔在每英寸點數較少 位圖列印後效果則比較模糊. 設定DPI值變大後圖檔則明顯變小,清晰度變高,發現列印條碼掃描槍能識别,至于大小可以通過移位替換方式高品質縮放的進行轉換:C#控制代碼

//縮放控制[高品質]     

 Bitmap getbitmap = new Bitmap(300,400);     

 Graphics newgra = Graphics.FromImage(getbitmap);     

 //插值算法品質控制     

  newgra.InterpolationMode = InterpolationMode.HighQualityBicubic;     

  newgra.DrawImage(DrawImg,new Rectangle(0,0,DrawImg.Width,DrawImg.Height),     

  new Rectangle(0,0,getbitmap.Width,getbitmap.Height),GraphicsUnit.Pixel);     

  newgra.Dispose();    

  return getbitmap; 

如上控制圖檔大小設定Width:300PX[像素] Height:400PX[像素] 可以自定義設定.

C#進行列印輸出控制後基本能夠完整列印: 效果:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134450234.gif"></a>

列印基本OK.

&lt;2&gt;DataMax-I-4208 DPL指令方式列印

當我們通過程式通用驅動方式去列印,發送給列印機是一張位圖Bitmap圖檔,輸出列印. DataMax DPL方式則更直接通過指令編碼實作對條碼列印精确控制. DPL程式設計時DAtaMax定義一套列印指令 完全不同InterMac和Zebar[斑馬]列印機. 如何獲得DPL Program HandleBook 程式設計手冊:

首先找到驅動盤,讀取驅動内容發現:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134458522.png"></a>

運作Do應用程式:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134507977.png"></a>

找到指定列印機類型: Data Max-I系列 即I-Class:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134516614.png"></a>

找到開發人員手冊PDF:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134526177.png"></a>

紅色辨別是驅動程式, 綠色辨別就是我們需要的Programmer HandleBook 開發人員手冊即DPL指令集如果你沒有驅動盤則可以如下連結方式下載下傳DPL完整指令集:

<a target="_blank" href="http://download.csdn.net/source/775181">DataMax-I-Class DPI指令集PDF下載下傳</a>

原始的DPL 指令集是全英的,總頁數多大350多頁, 我個人經驗是 針對這個DPL Programmer PDF 文檔不要過于盲目的去檢視, 主要是因為内容太多,而且大多數你都用不到, 是以在看這份文檔前 仔細的閱讀以下目錄會很容易找到你想要東西, .這點會讓你事半功力倍:

在DPL手冊查找指令前 要知道我們我們需要指令控制什麼因素: 針對BarCode Code 128格式做了大概分析影響因素如下:

&lt;1&gt;Print Speed列印速度[如果不是特别快或特别慢采用預設]

&lt;2&gt;Label Location 條碼坐标位置

&lt;3&gt;Chinese Control 中文字元處理 –預設情況列印中文是出現亂碼 ??? 需要額外配置

&lt;4&gt;Label Value 條碼值

&lt;5&gt;Label Frmat 條碼列印格式

既然有了需求 剩下工作也是不斷查找列印指令 測試輸出效果一個過程: 現在我們列印一個最為基本字元串大概來看一下DPL 指令格式 :

//列印一個字元串DPL指令     

&lt;STX&gt;L     

D11&lt;CR&gt;     

1T0000000150100ABCDEF&lt;CR&gt;     

121100000000100Barcode T&lt;CR&gt;     

DPL文檔并沒有對列印指令的文法格式進行說明,大多在說如何去設定 采用什麼樣指令, 說以在大概無數次測試中我也大概掌握DPL列印指令的基本文法格式 分享給各位[可能不準确]:

&lt;STX&gt;L:指定的是列印類型 &lt;STX&gt;L 自定列印一個條碼

Dll:則是對列印類型下更一步細分類似條碼 則分為Code 128 UPC-E 或二維碼等

&lt;CR&gt;: 類似C#每行代碼的; 指定目前本行指令結束符

E: 則是指定整段指令結束符 也就是說E 字元後面列印機自動不讀取識别的.

通過序列槽發送給列印機 指令完全正确 但DataMax-i-4208完全沒有反映,後來我聯系廠商才明白:

&lt;STX&gt;列印指令頭需要需要轉換16進制列印機才能識别 轉換後在TXT文本效果:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134535355.png"></a>

ok.通過序列槽工具發送指令給列印機 DataMax-i-4208終于開始響應 列印效果:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134543426.png"></a>

列印成功 DPL指令方式唯一不用擔憂的條形碼的品質 很清晰,指令這種模式做一個簡單類比 列印機就類似一個ATM取款機,不同的人攜帶不同的銀行卡即對應不同DPL 列印指令就能取到不同貨币美元 RMB等即對應列印結果.

而驅動方式 則前提是必須通過程式方式生成一張完整清晰的圖檔, 資料發送給列印機 列印采用自己設定和字庫進行畫出來列印.

那麼測試指令沒有問題如何通過C#程式設計方式發給列印機,再來看如何在程式設計中控制條碼的位置:

條碼列印在列印紙都有一個坐标位置對應X /y 很多人對于DPL指令如何條碼位置都很迷茫, 經過多方驗證得多結論 DPL設定:

Row OffSet 設定對應行起始位置就X坐标位置

Column Offset 設定對飲列起始坐标位置 即Y坐标位置

還有兩個參數:

ROW ADJUST(行調整) 以點為機關對行起始位置(ROW OFFSET)進行微調 

COLUMN ADJUST(列調整) 以點為機關對列起始位置(COLUMN OFFSET)進行微調

現在有了DPL參數名稱 我要告訴你不要就直接跑到 DPL 350頁大文檔裡去一點點去翻 給你一個直接簡單方式 利用PDF的查找快速定位你要找内容 雖然覺得這沒什麼 可是我要告訴你這種簡單效果 在一個非母語的文檔 效果還是非常好的:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134551322.png"></a>

詳細文法說明:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134600111.png"></a>

其他設定基本雷同,那麼在C#程式設計的話就要DPL指令格式限制問題. 類似我們制定X坐标即Row Offset的值 文法是R0037&lt;CR&gt;結束.首先X坐标的值範圍是0-9999,而且DPL規定格式必須是4位數. 也就是說類似設定X坐标為5 DPL标準識别格式:R0005&lt;CR&gt; C#進行控制:

/// &lt;summary&gt;     

/// 處理資料寬高格式0000 列印指令0010     

/// &lt;/summary&gt;     

public string ConvertDataFormat(float getvalue)     

{     

    string converstr = string.Empty;     

    if (!string.IsNullOrEmpty(getvalue.ToString()))     

    {     

        //Convert Float to int type    

        string getfromtint = Convert.ToInt32(getvalue.ToString()).ToString();    

        if (4 - getfromtint.Length &gt; 0)    

        {    

            for (int count = 0; count &lt; 4 - getfromtint.Length; count++)    

            {    

                getfromtint = "0" + getfromtint;    

            }    

            converstr = getfromtint;    

        }    

        else    

            //長度超過或等于格式長度4    

            if (4 - getfromtint.Length == 0)    

                converstr = getfromtint;    

            else    

                converstr = string.Empty;    

                throw new EquipmentException("設定列印元素初始列印位置超過本地列印機設定 設定小于等于4位數");    

    }    

    return converstr;    

針對&lt;STX&gt;列印标頭轉換 16進制控制:

/// Start Print CodeChar 指令:"&lt;STX&gt;L"      

/// 轉換成16進制AS#格式     

protected override string Leading()     

    #region 轉16進制資料     

    byte[] bytes = System.Text.Encoding.Default.GetBytes("&lt;STX&gt;L");     

    string reStr = string.Empty;    

    foreach (byte b in bytes)    

    {    

        short st = (short)(b - '\0');    

        reStr += st.ToString("x") + "%";    

    #endregion    

    return reStr;    

擷取字型方法:

//字型設定     

 using System.Runtime.InteropServices;     

 [DllImport("fnthex32.dll", CharSet = CharSet.Ansi)]     

 public static extern int GETFONTHEX(     

        string chnstr,     

        string fontname,     

        int orient,     

        int height,     

        int width,    

        int bold,    

        int italic,    

     StringBuilder cBuf); 

對于中文字型也就是Chinese Simple[中文簡體格式]是雙位元組 在DataMax中, 預設是不支援中文,類似我們把列印指令換成漢字 列印結果是出來字元亂碼 ??? 這是什麼問題. 我查了DAtaMAx官方對Chinese simple 中說明發現 如果需要DataMax列印中文則需要安裝字庫或在列印機上安裝中文字卡才能識别. 如果不安裝字卡 還有另外一種方式 采用第三方控件方式支援中文列印:

C#識别中文字元判斷:

/// 驗證是否是中文字元     

public bool IsChinese(string getvalue)     

return System.Text.RegularExpressions.Regex.IsMatch(getvalue, @"[\u4e00-\u9fa5]");     

DPL手冊中對Chinese Simple中文簡體列印方式做了詳細說明 詳見DPL PDF文檔手冊285/250/254頁:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134617918.png"></a>

針對DataMax中文列印問題 DPL手冊中給了一個列印漢字 盒 的例子 可惜這個例子 我經過N多次嘗試 通過序列槽發送列印DPL 始終沒能成功使用這個例子. 後來詳細研究這個DPL 檔案.發現針對中文設定的文法其實很簡單:

//列印漢字DPL文法     

&lt;STX&gt;L&lt;CR&gt;     

ySPM&lt;CR&gt;     

1911S0003100010P020P015 Chinese Available in GB r Set&lt;CR&gt;     

yUGB&lt;CR&gt;     

1911UC001200145P040P030&lt;BA&gt;&lt;D0&gt;&lt;00&gt;&lt;00&gt;&lt;CR&gt;     

1911UC001200190P040P040&lt;BA&gt;&lt;D0&gt;&lt;00&gt;&lt;00&gt;&lt;CR&gt;     

1911UC001200250P040P050&lt;BA&gt;&lt;D0&gt;&lt;00&gt;&lt;00&gt;&lt;CR&gt;    

1911UC001200320P040P060&lt;BA&gt;&lt;D0&gt;&lt;00&gt;&lt;00&gt;&lt;CR&gt;    

ySPM&lt;CR&gt;是列印語言和字型支援設定文法. ySPM是預設設定, yUGB則對應列印中文字型 這個設定很重要. 那麼我發現在DPL中并沒有漢字,其實DAtaMax針對列印漢字支援格式是GBK格式編碼 類似我們現在看到 漢字 盒 對應編碼就是&lt;BA&gt;&lt;DO&gt;&lt;OO&gt;&lt;OO&gt;. C#中預設字元UNICODE格式這個得注意 需要把漢字重新轉碼在傳入DPL指令中 列印機才能識别. 列印出來結果是 4個盒字:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134626745.png"></a>

在來說列印條碼Code128格式 DPL指令:

//列印Code 128     

1E000000015010001234567890&lt;CR&gt;     

121100000000100Barcode E&lt;CR&gt;     

輸出效果:

<a target="_blank" href="http://blog.51cto.com/attachment/201201/134634512.png"></a>

本文轉自chenkaiunion 51CTO部落格,原文連結:http://blog.51cto.com/chenkai/763885