從來沒想過自己會寫一篇博客,鑒於這次從未知的探索到一個個難點的攻破再到順利打印,很想記錄這些點滴,讓后人少走彎路。
下面走進正題。
需求:取數據庫里的相應的字段數據,並生成條形碼,可以批量、單條打印。大概意思就是你要搞出來一個高大上的標簽,可以貼在我的貨堆上。打印機我已經給你買好了,自己看着辦。
第一次接觸打印機器,我有點不知所錯。雖然在懵逼中恍惚了一會,但是打印機一到,三七二十一,紅紅火火恍恍惚惚,對於拼機器,我總是樂此不疲,半個小時搞定。直接給大家看下安裝好了的成果。好,上圖。
這就是支撐我們這次革命的硬件設施之一,條碼打印機。
好了,打印機方面的事情就不做過多贅述。鑒於打印機里有BarTender安裝的軟件,於是我走到了Bartender這條不歸路。
下面給大家聊下在BarTender上我走過的辛酸路。
首先打開BarTender,新建空標簽,過來人告訴你記得拿尺子量好標簽紙的長寬以及標簽紙間距設置完很省心很多,對於橫向縱向自己摸索,太細致的說我可能一兩天也說不完。
然后你可以按照需求做出你要的模版,大概就是醬紫。
模版好了以后,下面就在於取數據上了,在網上搜了好多關於BarTender數據源的方法。自己也做了嘗試,總結一下歸為兩類,一類是數據庫的連接,一類就是文檔信息讀取如(Excel)
在綁定好數據源以后,就可以對你想要的個別字段進行數據綁定。
如果只是在本機打印的話,你基本上可以為所欲為。當時為了區分已打印和未打印,蛋疼了很久,結果后來發現Bartender支持存儲過程,本機打印的,這絕對是福音,看下圖的自定義sql。綁定的數據源,可以取出你想要的數據,在處理已打印和未打印的問題上,存儲過程,你值得擁有!
在綁定好數據源后,在代碼中進程調用exe即可打印:代碼如下
/// <summary>
///
/// </summary>
/// <param name="filePath">程序路徑</param>
/// <param name="BTW_File_Name">模版名稱</param>
/// <returns></returns>
public Result<string> Print(string filePath, string BTW_File_Name) { try { Process myprocess = new Process(); myprocess.StartInfo.FileName = "bartend.exe";//需要啟動的程序名 if (System.IO.File.Exists(Path.Combine(filePath, "bartend.exe")) && System.IO.File.Exists(Path.Combine(filePath, BTW_File_Name + ".btw"))) { myprocess.StartInfo.FileName = "bartend.exe";//需要啟動的程序名 myprocess.StartInfo.Arguments = "\"/f=" + BTW_File_Name + ".btw\" /p /x";//啟動參數 myprocess.StartInfo.WorkingDirectory = filePath;//需要啟動的程序所在文件夾 myprocess.Start();//啟動 Process[] KillmyProcess = Process.GetProcessesByName("bartend.exe"); foreach (Process process in KillmyProcess) { process.Kill(); } return new Result<string>(true, "打印模版沒數據!"); } else { return new Result<string>(false, "請確保BarTend應用程序和模版是否存在!"); } } catch (Exception ex) { return new Result<string>(false, ex.ToString()); } }
以上是缺陷就是數據源必須寫死,根據一個字段來區分已打印和未打印。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------華麗分割線------------------------------------------------------------------------------------------------------------------------------
以上方法沒有涉及到 BarTender的SDK方法。下面給大家說下利用Bartender中的Seagull.BarTender.Print.dll進行相應的開發。(Bartender安裝文件下的權限最好加一個everone加上所有的權限)
try { string PrintName = "TSC TTP-243E Pro";//"TSC TTP-243E Pro" AppLogger.Warn("引擎new之前");//"記錄日志方便查找問題原因" Engine btEngine = new Engine(); AppLogger.Warn("引擎new完后,start前"); btEngine.Start(); AppLogger.Warn("引擎開啟"); LabelFormatDocument btFormat = btEngine.Documents.Open(Path.Combine("C://Program Files (x86)//Seagull//BarTender Suite", "模版1" + ".btw")); AppLogger.Warn("模版打開"); btFormat.SubStrings["ProjectNo"].Value = DataImportOld.Project_Name;//對模版相應字段進行賦值 btFormat.SubStrings["ProjectName"].Value = DataImportOld.Material_Name; btFormat.SubStrings["GroupName"].Value = DataImportOld.WorkingGroup_Name; btFormat.SubStrings["Type"].Value = DataImportOld.Material_Type; btFormat.SubStrings["Color"].Value = DataImportOld.Color; btFormat.SubStrings["Num"].Value = Convert.ToString(True_Number); btFormat.SubStrings["BarCodeName"].Value = builder.ToString(); btFormat.SubStrings["Batch"].Value = DataImportOld.Batch; AppLogger.Warn("模版賦值"); //btFormat.PrintSetup.Cache.FlushInterval = CacheFlushInterval.PerSession; //btFormat.Close(SaveOptions.DoNotSaveChanges);//不保存對打開模板的修改 btFormat.PrintSetup.PrinterName = PrintName; //尋找打印機 PrinterSettings.StringCollection snames = PrinterSettings.InstalledPrinters; bool PrintIsExist = false; string logPringter = ""; foreach (string Name in snames) { logPringter += Name + ";"; if (Name.ToLower().Trim() == PrintName.ToLower().Trim()) { PrintIsExist = true; } } AppLogger.Warn("搜索的打印機有" + logPringter); if (!PrintIsExist) { return new Result<string>(false, "打印機不存在"); } AppLogger.Warn("開始打印"); btFormat.Print(); AppLogger.Warn("打印成功"); AppLogger.Warn("開始關閉引擎"); btEngine.Stop(); AppLogger.Warn("關閉引擎成功"); } catch (Exception ex) { AppLogger.Warn(string.Format("Exception: " + ex.Message)); return new Result<string>(false, string.Format("Exception: " + ex.Message)); }
上面截取了一段代碼,完全可以實現模版下的為所欲為。規定好模版,然后把你取的數據賦值到相應的標簽下即可。
例如:btFormat.SubStrings["ProjectNo"].Value = "為所欲為";
當時在做模版Btw的時候確實蛋疼過這個ProjectNo怎么標識讓程序讀懂,綁定數據源又不可以直接綁定,着實瘋了一段時間,最后摸索出來Bartender下如何設置標識。上圖:
就這么簡單。。。。。。不過摸索起來,自己一個一個打印嘗試簡直要人命,我不願回憶。。。
好了,說到這里大家覺得我的問題基本解決了。過了段日子,當我把網站部署到服務器上的時候,然后想到條碼打印這塊,隱約感覺到!@#¥%@#¥%%……&對,這就是我的心情
發布到iis 涉及很多權限問題,網上扒了一下,有如下幾個方法解決相關問題,感謝這些給出解決方法的達人們。
“iis默認是用network service這個賬戶去執行一系列操作的,包括之前SDK中寫到的,btEngine.Start();這句代碼。這就跟在web上執行打開excel或word文件是一樣的。network service賬戶默認是沒有對bartender模板文件的讀寫權限的。所以這里我們需要設置一下network service的權限。控制面板》管理工具》組件服務》計算機》我的電腦》DCOM配置找到以bartender單詞開頭的幾個服務。右擊服務》屬性》安全 全部改為自定義 並且這三項編輯里面添加賬戶,加入 network service賬戶,並給與其最大權限。然后我們回到iis上,選擇我們發布的網站》雙擊身份驗證(在內容視圖界面)右鍵ASP.NET模擬》編輯》特定用戶》設置》填寫administrator賬戶及密碼(注意必須為administrator賬戶設置密碼)”
發布到服務器上以后就遇到了客戶端打印的問題。
在解決web客戶端打印的問題上推薦一篇很好文章http://blog.csdn.net/thecityofsky/article/details/6713870。其實最好的方法是做個相應的插件,可惜自己對插件這塊還是一片空白,所以在糾結完各種方法后。自己還是做了一個super simple客戶端,通過wcf對相應數據進行監控,數據推送打印任務后調用客戶端的打印機進行打印。盡管方法不如插件之類的高大上,但是解決了現有的問題。下面展示下打印的成果,關於隱私的東西已經打碼,哈哈哈
好了,到這里已經差不多了,相關的dll和樣例我都打包在這里了http://download.csdn.net/detail/jafic/9585409。有興趣的可以下載看看。
Ps:30天過去了,Barternder試用功能沒有了。鑒於工廠需要多台打印機購買安裝正版Bartender需要很大的成本,於是我走上了告別Bartender之路。
鑒於我們的打印機是TSC,它也提供了相關的接口dll,因此最后直接告別Bartender軟件直接打印條碼。
關於TSC的解決方案、dll我都打包在了這里,有興趣的可以下載看看http://download.csdn.net/detail/jafic/9585459
謝謝大家,轉載請標注來源~
技術無罪,請尊重知識分享