【转】BarTender与ASP.NET的集成小结(条码标签打印编程)

简介: 话说自从上次发了篇NHibernate的资料后,好久没有写东西了,半年来一直在忙一个项目,做完项目后,发现很多东西虽然当时做了,懂了,但是很快就会模糊了,于是又再想起总结的重要性~~没啥地方好放资料的,放在博客园也是一个不错的选择~~   本人也是新手,写的不好的地方,请多原谅。

话说自从上次发了篇NHibernate的资料后,好久没有写东西了,半年来一直在忙一个项目,做完项目后,发现很多东西虽然当时做了,懂了,但是很快就会模糊了,于是又再想起总结的重要性~~没啥地方好放资料的,放在博客园也是一个不错的选择~~

 

本人也是新手,写的不好的地方,请多原谅。如果发现有什么错误,请指出,我会更改的,谢谢!

 

本文章做探讨交流只用,欢迎转载,转载请注明出处,谢谢!

 

BarTender是一款优秀的条形码打印软件,可以支持很多种类型的条形码设计和打印,具体大家可参考他的官网(http://www.seagullscientific.com/aspx/products.aspx),这里不多介绍。

本来在做SilverLight的东西的,后来项目有需求,说要在系统里加入条形码的设计和打印功能,PM提出两个方案,一个就是自己去开发一个条形码设计器,这样的好处就是跟系统的集成使用比较方便,但是开发这个设计器又是一个比较大的Task;另外一个方案就是使用客户原有的BarTender软件,把软件集成到系统中,那么设计部分还是交由BarTender去完成,我们的系统只需开发集成的部分就好。经过商量,大家决定了采取集成BarTender的方案,于是就要找人去做技术攻关了,跟原来的Partner商量了一下,他说想继续深入学习SilverLight,我就想去涉猎更多的东西,于是刚好,分道了~~

在刚开始接触BarTender的时候,发现网上的资料很少,我是把他们官网上的资料都看了,什么白皮书啊,向导之类的都看了。我们的系统是ASP.NET做的,通过一段时间的学习,知道了BarTender的几种集成模式。ActiveX COM集成,Commander的触发式集成,还有9.0版本后支持的.NET SDK的支持。简单说说这几个方式:

1、              ActiveX COMBarTender在你的机器上安装好后,会在机器上注册一个COM,你在程序中可以调用这个COM,使用他提供的方法和属性,进行BarTender的程序级控制。这个集成方式比较实用,对BarTender的版本要求低,不过因为是基本的COM使用,所以要求你对COM的接口比较熟悉,对整个BarTender的调用流程和细节比较清晰,对于COM接口的描述,大家可以参考Automation.chm这个帮助文档(在Seagull\BarTender Suite\BarTender目录下)。

2、              Commander的触发式集成:简单来说,这个是通过配置BarTender,让他监视某个文件,当程序生成这个文件的时候,就会触发唤醒BarTender进行打印工作,这种方式我觉得不大好用,所以了解也不多,欢迎讨论交流。

3、              .NET SDK:这个是9.0版本开始支持的一个适用于.NET框架的SDK,里面提供了很多类来进行BarTender的控制,由于这个SDK也是用.NET编写的,所以对于用在.NET下的集成非常方便,不过由于对版本有要求,所以要考虑客户的成本来使用。

一、.NET SDK

我们的项目开始的时候是使用.NET SDK 的,因为那时都还没有搞清楚客户是需要在服务器打印还是客户端打印,老大就要求先开始研究了,这个很气人!做了许久才说客户要在客户端打印,把之前做的一切东西都推翻了~~

.NET SDK里面分开了两个,一个是标准的,一个是Server版的,标准的只是简单的开启BarTender进程去处理打印任务,所以当有多个任务同时打印的时候,就需要自己去管理任务队列问题;而Server版的就是里面有了任务队列机制,很方便的管理任务队列和BarTender的进程资源。但是Server版需要安装BarTenderEnterprise版才支持,ORZ~~什么都是钱~~

1、              SDK其实底层上也是对COM的调用,只不过封装了,让开发者更好操作,标准的SDK应该看帮助文档没什么问题,里面对各个类以及他们的方法和属性都做了详细的解释。下面给出一段代码,里面代表了最简单的典型使用:<!--[endif]-->

        首先添加引用,在.NETTAB里面可以找到Seagull.BarTender.Print

        然后,在程序里添加命名空间引用 using Seagull.BarTender.Print;

        之后程序的简单使用如下:

            //new an BarTender engine

          Engine engine = new Engine(true);

          //use the engine to open a format document to return a LabelFormatDocument object

          LabelFormatDocument format = engine.Documents.Open("c:\\test.btw");

          //use the LabelFormatDocument object to print

          format.Print("Select printer", out messages);

            使用完成后记得回收相关资源。

  2、              对于Server版的SDK,我在这里稍微的描述一下他的队列管理详细吧,不过单纯使用SDK是不需要知道这些东西的,使用上跟标准的SDK一样简单,只要参考帮助文档和Samples就可以很好明白了。写出他的队列管理详细仅供大家探讨~~大家看这一部分源码的时候,要先看一下线程的相关知识。<!--[endif]-->

      1) 程序流程核心是:把任务放进任务队列里,任务队列检测到有任务在排队的话,就把任务扔到引擎管理中,选择一个空闲的引擎来执行任务。

      2) 管理任务队列主要是使用BtPool类,这个类里面的Consume函数不断地检测队列是否为空,如果不为空,则开始任务的提交工作,先通过engine.Status != TaskEngineStatus.Busy来检测空闲的Engine,然后通过engine.SubmitTask(this.m_masterTaskQueue)来提交任务到Engine里。

    SubmitTask函数里面,我们可以看到把扔进来的任务付给当前引擎对应的任务的句子:

      this.m_task = tasks.Dequeue();

    然后我们查看管理引擎的主要类TaskEngine,可以看到里面同样有一个Consume函数,他会不断检测当前引擎对应的任务是否为空,不为空则开始执行任务。

    因此,当SubmitTask函数里通过this.m_task = tasks.Dequeue()把任务赋给了当前引擎的任务后,就会开始任务执行的Task.Run()方法。

    Task.Run()方法里,根据多态的特性,调用this.OnRun()的时候,是调用了PrintLabelFormatTask类的OnRun()方法。在PrintLabelFormatTask类的OnRun()方法里就实现了把任务发送到打印机或者打印成文件的工作。

       BtPool 管理任务队列和引擎池。 TaskEngine 对应的是一个引擎。 TaskQueue 为队列的相关操作的类。 TaskEngines TaskEngine 的相关操作的类。

  3、              大家可能看到网络浏览器的打印例子,里面写到了客户端的打印,这个客户端的打印其实也是在服务器上做,但服务器上做的只是把打印的结果输出为一个打印文件,然后把文件传送到客户端,客户端再通过JaveScript调用本地的打印机读取打印文件进行打印。这个要求服务器和客户端都装有同一个打印机驱动,而且客户端真正打印时使用的打印机驱动,要跟服务器上用来生成打印文件的打印机驱动一致。这里也有对这种方式的一些资料,仅供参考:<!--[endif]-->

1WebLabelPrint客户端打印

 //设定打印到文件

labelFormat.PrintSetup.PrintToFile = true;

//设定打印机

      labelFormat.PrintSetup.PrinterName = compatibleServerPrinter;

      //设定打印机的License

labelFormat.PrintSetup.PrintToFileLicense = Request.Form.Get(_listPrinters.PrintLicenseUniqueID);

      string tempFullPath = (string)Application["TempFolderFullPath"];

//设定打印文件的路径

           labelFormat.PrintSetup.PrintToFileName = System.IO.Path.Combine(tempFullPath,Guid.NewGuid().ToString() + ".prn");

2)设定好以上东西后,就像正常的服务器打印一样,把任务发送到任务队列,当打印完成的时候,调用函数TaskPrint_Succeeded,里面将printTask.PrintCode读取出来,然后把打印码发送到本地的打印机进行打印。

3ClientPrinting.js PrintList.aspx页面里用到GetClientPrinters函数,完成客户端打印的主要是BarTenderPrintClient.jsWebLabelPrintSample.js文件。

4BarTenderPrintClient.js文件里主要包含了一些针对打印机的操作,如获得打印机列表,匹配服务器和客户端的打印机,获得打印机的License,还有就是把打印码发送到对应的打印机上。

 

        5 WebLabelPrintSample.js 文件主要包含了将客户端打印机列表填充到 DropDownList 里( PrintListControl.ascx ),将客户端打印机列表填充到 Table 里( Printers.aspx )。 <!--[endif]-->

二、ActiveX COM

         在我呕心沥血看了好久的SDK,把他的源码反编译出来慢慢研究了几个星期后,老大说要在客户端进行打印~~顿时内牛满面~~我跟老大说起上面的那种先生成打印文件,再发送到客户端的打印方式,老大说不行,最好少跟服务器进行通信,因为他们的网络环境不怎样~~郁闷了~~Senior的提醒下,开始对ActiveX进行研究~~主要的思路是想通过做出一个ActiveX插件,然后进入页面的时候在客户端进行安装,然后对客户端机器上的BarTender进行控制~~既然是用ActiveX,那就使用BarTender提供的最简单的COM就行了~

               COM 里面主要的就那么几个类,下面一一详细说明:<!--[endif]-->

1)           Application类:实际上代表一个BarTender的进程,当你新建一个此类的对象的时候,就会出现一个新的BarTender进程。

2)           Format类:实际上代表一个格式标签(BTW文件),使用Application. Formats.Open()方法可以打开并返回一个Format对象。这个类里面包含了打印设置,标签的参数设置等一系列的设置,很重要的一个类。

3)           NamedSubString类:管理标签文件里所有SubString的类。

4)           DataBase类:管理标签文件里设置的所有数据库链接的类。

 

    5)      QueryPromts 类:管理标签文件里面数据库查询参数的类。

 

         <!--[endif]-->鉴于Format类是比较重要的类,这里再对他的相关属性和方法也做一下说明:<!--[endif]-->

1) Print方法:这个就是最常用的打印方法,里面可设置打印的任务名,是否等待打印完成,等待超时时间,打印过程输出的信息。

2) PrintOut方法:如果你需要在打印时出现打印设置对话框和状态框,你可以选择这个方法来实现。

3) Save方法:保存对Format的更改。

4) SetNamedSubStringValue方法:设置某个特定的SubString的值,这里就可以作为一个动态改变打印内容的方法。

5) SetPromt方法:跟SetNamedSubStringValue方法类似,不过他设置的是打印提示的值,某些标签通过设置可以在打印的时候弹出对话框,输入某些变量的值来改变打印内容,这个方法就是动态设置这些变量的。不过在集成中比较少用。

6) IdenticalCopiesOfLabel属性:这个是设置打印时要打印多少份相同的标签的,默认为标签设置。

7) NumberSerializedLabels属性:这个是序列化打印时使用的,当你的标签启动了序列化后,这个属性代表的就是打印的份数,譬如你的序列化初始数据是1,增量为1NumberSerializedLabels设置为5,那么就会打印出12345,五个标签出来。

8) Printer属性:指定要使用的打印机,默认为系统指定的默认打印机。

 

9)     PrintToFile 属性:标示是马上用打印机打印出实物,还是生成一个打印文件。<!--[endif]-->

通过上面方法的解释,大家已经看到里面已经有几种动态控制打印内容的方式了,我在项目中使用了上面两种,一种是直接通过SetNamedSubStringValue方法去设置某些变量的值,然后进行打印,这个适合小量的打印,因为每次都要调用ApplicationFormat对象来处理,所以打印100份就要调用一百次,效率低,但是可以灵活设置每次的打印内容;另外一种是使用序列化打印,这个的效率就高了,因为他是只调用一次把数据扔给BarTender,之后的都是BarTender根据序列化规则去生成打印内容,不过这个方式就欠缺灵活性,只适用于标签的内容是有一定的规律进行变化的大批量打印。

上面还提到了DataBaseQueryPromts类,这两个类是用在连接数据库的打印中的,这个是我用到的第三种动态控制打印内容的方法。主要思路是,在标签里设置好各项内容,这些内容都是对应数据库的某些字段,然后设置好查询条件,暴露一个或多个查询参数,然后在程序里通过QueryPromts类来设置这些查询参数来查询出不同的数据库内容,达到动态改变打印内容的目的。Format.Databases.QueryPrompts.GetQueryPrompt()可以特定的查询条件,然后通过设置Value属性来设置他的值,最后设置完所有查询条件后进行打印。

关于这几种动态控制打印内容的方法,都是要设计标签文件和程序相互配合的,比较不灵活,其实可以做成更好的动态配置方式的,不过老大说没必要,就放弃了。至于要是有朋友不了解标签文件的设计,我有时间会写一个文章来专门说标签文件的设计的。

<!--[endif]-->

三、集成

     有了上面的介绍后,大家对BarTender提供的集成信息有了一定的了解了。我是采用了ActiveX COM的方式,而且我的是客户端打印,于是我也做了个伪ActiveX插件,为什么叫“伪”呢?因为他不是传统意义上的ActiveX,而是用C#编写的(悔恨当年没学C++),所以叫“伪”。关于制作伪ActiveX,网上有很好的教程,我这里就给个链接算了(http://www.cnblogs.com/homer/archive/2005/01/04/86473.html)。

         在做好ActiveX并确定部署好后,在网页上调用ActiveX插件就需要用到JavaScript了,大家在部署ActiveX的网页上,会有下面这样一句代码:

        <object id="BTDPrintClient" classid="clsid:{0750A7B0-CF1E-4EAD-8C73-E0C8F6D9E890}" codebase="CAB/BarTender_AX.cab"></object>

       这里也提醒一下,第二个属性的名字是classid,然后里面设置的字符串的开头那几个是clsid,是不同的,我当时就在这里没注意,部署了好久都不行。

       回到JavaScript的调用上来,在调用时,主要就是下面的代码:

            printClient = new ActiveXObject("BTDPrintClient.PrintClient");

     这里应该很好理解,就是创建BTDPrintClient这个object对象里面的PrintClient对象。完成这一句后,printClient就等于是一个PrintClient的对象了,你可以在JavaScript里面调用PrintClient的各种方法属性了,于是就可以控制本地的BarTender了。 

 

四、小结

         做一个东西的集成,我觉得首先你是必须要去很了解这个要集成的软件,可以通过上网搜索资料,官方文档,最重要的还是软件自身的一些帮助文档和API文档,基本软件的信息都在里面了。而且这次做集成我还联系上了BarTender的亚太区这边的技术支持,也给我带来了不少帮助,虽然他们是要购买产品才能提供支持,但是初步的支持还是可以提供的,你只要跟他们说在用他们的试用版进行集成测试,看效果如何再决定要不要购买产品,哈哈~~引诱引诱~~

         还有在做一个新的东西的时候,还是建议多动手吧,做些小Demo来验证一下想法,认真调试一下追踪问题。不动手是没办法可以很好的理解一样东西的,所以,做IT,累死了~~什么时候上天砸些钱给我啊?烧香去~~~

目录
相关文章
|
3月前
|
XML 开发框架 .NET
ASP.NET COR3.1 集成日志插件NLog
ASP.NET COR3.1 集成日志插件NLog
32 0
|
4月前
|
XML SQL 开发框架
|
3月前
|
机器学习/深度学习 算法
机器学习 - [集成学习]Bagging算法的编程实现
机器学习 - [集成学习]Bagging算法的编程实现
32 1
|
6月前
|
JSON 开发框架 .NET
ASP.NET Core 集成JWT
什么是JWT?Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也...
233 0
ASP.NET Core 集成JWT
|
3月前
|
IDE 前端开发 JavaScript
【C#】C# 开发环境配置(Rider 一个.NET 跨平台集成开发环境)
【1月更文挑战第26天】【C#】C# 开发环境配置(Rider 一个.NET 跨平台集成开发环境)
|
5月前
|
存储 SQL 监控
.NET开源简单易用、内置集成化的控制台、支持持久性存储的任务调度框架 - Hangfire
.NET开源简单易用、内置集成化的控制台、支持持久性存储的任务调度框架 - Hangfire
|
6月前
|
开发框架 .NET 数据库
asp.net企业费用报销管理信息系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
asp.net 企业费用报销管理信息系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使 用c#语言开发 应用技术:asp.net c#+sqlserver 开发工具:vs2010 +sqlserver
48 0
|
7月前
|
容器
.NET Core - 选项框架:服务组件集成配置的最佳实践
.NET Core - 选项框架:服务组件集成配置的最佳实践
|
9月前
|
开发框架 前端开发 安全
ASP.NET Core MVC 从入门到精通之Html辅助标签补充及模型校验基础
ASP.NET Core MVC 从入门到精通之Html辅助标签补充及模型校验基础
91 0
|
9月前
|
开发框架 前端开发 .NET
ASP.NET Core MVC 从入门到精通之Html辅助标签(一)
ASP.NET Core MVC 从入门到精通之Html辅助标签(一)
72 0