从来没想过自己会写一篇博客,鉴于这次从未知的探索到一个个难点的攻破再到顺利打印,很想记录这些点滴,让后人少走弯路。
下面走进正题。
需求:取数据库里的相应的字段数据,并生成条形码,可以批量、单条打印。大概意思就是你要搞出来一个高大上的标签,可以贴在我的货堆上。打印机我已经给你买好了,自己看着办。
第一次接触打印机器,我有点不知所错。虽然在懵逼中恍惚了一会,但是打印机一到,三七二十一,红红火火恍恍惚惚,对于拼机器,我总是乐此不疲,半个小时搞定。直接给大家看下安装好了的成果。好,上图。
这就是支撑我们这次革命的硬件设施之一,条码打印机。
好了,打印机方面的事情就不做过多赘述。鉴于打印机里有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
谢谢大家,转载请标注来源~
技术无罪,请尊重知识分享