关于WEB应用程序的打印组件开发初探

 

一、引言

  近些年来,随着互联网的普及和推广,传统的单机模式和局域中的C/S模式的应用程序越来越不能满足信息共享的要求。因此,一种新的基于浏览器的B/S的应用程序的开发方式被提了出来。新的开发方案以其客户端的免维护、免配置、程序能根据服务器的信息能够自动更新升级;服务器端多层模式的应有提高处理的效率和安全性越来越被广大的应用程序的开发者所看好。成为应用程序开发的一个新的发展方向。在WINDOWS的平台上,人们利用ASP来开发服务的显示界面,而用组件来封装商业规则,在各种杂志上利用各种工具进行组件开发也是屡见不鲜。但介绍打印组开发却不怎么看到。笔者希望就自已开发打印组件的一点心得体会来抛砖引玉。

 

二、设想

  WEB打印组件要求是在一次为某单位开发信息管理系统中被提及的,这个系统中的一些票据需要打印。这样,如何对这些票据进行套打成了我们必须解决的问题。

  要在客户端打印一些用户要求的票据或其它的文字或图片资料,有两种方式:一种是利用DELPHI的ACTIVE FORM来生成客户端的界面,由浏览器下载安装,并在客户端运行。(这种方式在开发多后台数据库中,较为常用。在国内许多新版本的财务软件都采用了这种方法,其缺点是对开发人员的要求太高),另一种是开发一个组件在客户端安装,然后,由服务器端来生成VBSCRIPT脚本,在客户端运行、创建相应的组件对象;利用组件对象来进行打印操作。(这种方法只要客户端的COM组件开发完成,使用者只要熟悉VBSCRIPT或JAVASCRIPT脚本语言就可能方便的调用)。本文我们主要讨论第二种方式。

 

三、实现

  首先、运行DELPHI 5.0;选择FILE菜单中的NEW,在弹出的对话框中选择ActiveX页,选择ActiveX Library创建ActiveX库.然后,再往新建的库中加入一个Automation Object,操作步骤同上。在Automation Object Wizard对话框中填入组件名prtTest3;单击OK。

  然后、在弹出的PrtTest3.tlb窗口中,选择IPrtTest3。单击右键新增一个IsInit的Property,类型为long。再继续增加如下5个Method:

  procedure prtCustomPage(PageWidth: Integer; PageHeight: Integer);
       safecall;

  procedure prtStart; safecall;

  procedure prtNewPage; safecall;

  procedure prtEnd; safecall;

  procedure prtDrawLine(X1: Integer; Y1: Integer; X2: Integer; Y2:
       Integer; LineWidth: Integer); safecall;

  procedure prtSetFont(const FontName: WideString; FontSize:
       Integer); safecall;

  procedure prtTextRect(VAlign: Integer; HAlign: Integer; RectLeft:
       Integer; RectTop: Integer;RectRight: Integer; RectBottom:
       Integer; const PrintString: WideString); safecall;

  它们意义是:prtCustomPage   用来设置自定义纸张.传入的参数自定义纸张的宽度和高度。

        prtStart    用来初始化打印机。如果初始化成功,则将属性IsInit置为真,反之则为假。 

        prtNewPage    用来使打印机换页。

        prtEnd     结束打印任务。

        prtDrawLine    用来在页面上绘制一条线。(X1,Y1)为起始点.(X2,Y2)为终止点。LineWidth为打印线的宽度。

        prtSetFont    用来设置打印的字体名及大小。

        prtTextRect    用来指定的方框内的输出的指定的字符串。

 

四、调用

 

在脚本中调用这个组件的方法:

(1)、利用CreateObject函数创建一个打印对象。

(2)、调用prtCustomPage来指定定制的纸张的大小(以0.1毫米为基本单位)。如果,不是定制的纸张则不需要调用这个过程(即以打印默认的纸张大小进行打印)。

(3)、调用prtStart进行打印机的初始化工作。如果打印机初始化成功,则会将IsInit属性置为真,表示初始化成功;否则,表示打印机正在忙或有别的应用程序正在使用打印机,初始化不能成功。

(4)、判断IsInit标志。如果为真,则继续执行打印段。

(5)、执行打印段。可以在利用打印机画线、和在指定位置输出文字。

(注:在组件接中的所有位置单位都是0.1毫米。例如.prtObject.prtDrawLien 0,0,1000,1000 表示从左上角(0,0)毫米到右下角(100,100)毫米处,画一条直线)

(6)、利用prtEnd结束打印任务。

<SCRIPT LANGUAGE="VBScript">

<!--

 Sub TestPrtObject

   Dim prtObject

   Set prtObject=CreateObject("PrtTest3.PrtTest3")

 

   prtObject.prtCustomPage 1000,1000

   prtObject.prtStart

 

   if prtObject.IsInit then

     prtObject.prtDrawLine 0,0,1000,1000,1

     prtObject.prtDrawLine 500,700,1000,1000,1

     prtObject.prtSetFont "宋体",16

     prtObject.prtTextRect 2,2,0,0,1000,500,"WEB应用程序打印测试"

     prtObject.prtEnd

   end if

 

   Set prtObject=Nothing

 End Sub

 

  TestPrtObject()

//-->

</SCRIPT>

 

五、代码解析

  在这个组件中,我们所要解决的几个问题:

(1)、在Delphi的应用程序设计中自定义打印纸张的设置,Delphi中自身带了一个QuickReport的打印设计程序,这个程序在一定的程度上方便了打印的设计,但这个设计程序对于自定义纸张的设定和打印支持却不是很好。因此,在这个组件中我们采用手工代码来设定自定义纸张大小。

Function TPrtTest3.InitPrintPaper:Boolean;

Var

   Device:Array [0..cchDeviceName-1] of Char;

   Driver:Array [0..(max_path-1)] of Char;

   Port:Array [0..32] of Char;

   hDMode:THandle;

   pDMode:PDevMode;

Begin

   Result:=True;

   if PrtIsCustomPaper then

    Begin

       {设置打印机段}

       Printer.GetPrinter(Device,Driver,Port,hDMode);

 

       if hDMode<>0 then Begin

         Try

           pDMode:=GlobalLock(hDMode);

           if pDMode<>nil then Begin

         //设定打印的方向为纵向或横向

             if PaperOrientation<>0 then
         pDMode^.dmOrientation:=DMORIENT_LANDSCAPE

             else pDMode^.dmOrientation:=DMORIENT_PORTRAIT;

       //设置拷贝份数为1份.

             pDMode^.dmCopies:=1;                       

       //以毫米为单位的纸张大小.

             pDMode^.dmPaperLength:= PaperHeight*10;    

             pDMode^.dmPaperWidth:=PaperWidth*10;

       //设置纸张类型为用户自定义.

             pDMode^.dmPaperSize:=DMPAPER_USER;         

           end;

           GlobalUnLock(hDMode);

           Printer.SetPrinter(Device,Driver,Port,hDMode);

         except

           Result:=False;

         end;

       end else Begin

         Result:=False;

       end;

    end;

end;

(2)、打印位置的确定:由于组件是以图形方式进行打印,这就使得我们可以精确指向打印文件的输出位置,以便于进行对某些票据的套打。但这样就产生一个问题,我们是以打印的像素位置指定输入位置,还是以打印尺寸来指定位置。显然,利用像素来输出打印位置,对于编制程序来说是比较方便的。但由于一般用户对像素的概念并不理解,因此会带来使用上的困难;而且每一种打印机的分辩率是不一样的,因此,会出现在不同打印机上打印的效果不一样的问题。而以打印尺寸来指定位置并在程序中妥善加以处理就不会有上面的问题。具体的处理方法是,由用户输入尺寸位置。然后,在打印时,首先取得当前打印机的分辩率(注意:分辨率是以每英寸多少像素为单位的),再计算得出实际输入的像素位置后进行打印,这样就可以使得组件更加实用,而且,保持打印幅面的一致。具体的函数如下。

Function TPrtTest3.MMtoPrintPixel(InputPoint:TPoint):TPoint;

Begin

   Result.x:=MMtoPrintPixelX(InputPoint.x);

   Result.y:=MMtoPrintPixelY(InputPoint.y);

end;

 

Function TPrtTest3.MMtoPrintPixelX(InputX:Integer):Integer;

Begin

   if QueryPrintlogPixel then

    Begin

       pDDIx:=GetDeviceCaps(Printer.Handle,logPixelsX);

       pDDIy:=GetDeviceCaps(Printer.Handle,logPixelsY);

       QueryPrintlogPixel:=False;

    end;

   Result:=Trunc(InputX/253.8*pDDIx+0.5);

end;

 

Function TPrtTest3.MMtoPrintPixelY(InputY:Integer):Integer;

Begin

   if QueryPrintlogPixel then

    Begin

       pDDIx:=GetDeviceCaps(Printer.Handle,logPixelsX);

       pDDIy:=GetDeviceCaps(Printer.Handle,logPixelsY);

       QueryPrintlogPixel:=False;

    end;

   Result:=Trunc(InputY/253.8*pDDIy+0.5);

end;

GetDeviceCaps:为Windows系统中取得指定设备信息的函数。函数的原型如下

int GetDeviceCaps(

    HDC hdc,    // 设置的句柄

    int nIndex     // 查询的设备参数。 

   );

其中,HDC为想要查询的打印机的句柄,logPixelsX、logPixelsY表示要查询的内容是打印机横向、纵向的每英寸的像素点数。

 

六、组件的注册

  如果是在Delphi编写了这个组件的,则可以选择Run菜单下的Register ActiveX Server来进行这个组件的注册。

  对于不开发机器的注册则可使用:点击“开始”→“运行”;在运行对话框中输入以下命令:

  regsvr32  < 文件名 >        注册一个ActiveX控件

  regsvr32  /u  < 文件名 >    解除某ActiveX控件的注册

 

七、其它应用

  组件的扩展:以上列出的仅仅是编写这个组件的框架,功能比较有限。根据需要我们还可以添加上画圆、椭圆,矩形,甚至图片等功能。有兴趣的读者就请自行添加。

因为,组件是采用COM的方式运行,所以,我们还在Window Script Hosts(WSH)中应用这个组件,结合WSH原有(通过ADO对象)访问外部数据库的能力,就可能做出在WINDOWS下功能强大的WSH的脚本程序。

源程序请到程序员杂志频道下载.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iptables 是一种在 Linux 操作系统上广泛使用的防火墙工具。它能够通过过滤、修改和重定向网络数据包来加强服务器的安全性。 首先,iptables 可以根据源和目标 IP 地址、端口号和协议类型等条件对网络数据包进行过滤。例如,我们可以配置 iptables 来阻止特定 IP 地址或端口的流量进入服务器,从而避免潜在的安全威胁。此外,我们还可以通过 iptables 的用户定义链来进行更复杂的过滤操作。 其次,iptables 还可以修改数据包的头部信息。通过修改数据包的源或目标 IP 地址等信息,我们可以实现网络地址转换(NAT)功能,将私有 IP 地址映射为公共 IP 地址以实现 Internet 访问。此外,还可以通过修改数据包的源或目标端口号来实现端口转发等功能。 最后,iptables 还可以根据一系列规则来重定向数据包。例如,我们可以配置 iptables 将特定端口号的流量重定向到不同的服务器,以实现负载均衡或高可用性。同时,iptables 还支持连接跟踪,可以跟踪连接状态,并根据连接状态来处理数据包,从而提供更高级的安全防护。 在实际应用中,我们可以使用 iptables 命令来创建、修改和删除规则。同时,为了简化配置过程,还可以使用一些图形界面的工具,如 firewalld 和 UFW,来管理iptables。需要注意的是,正确地配置 iptables 规则非常重要,因为不当配置可能会导致网络连接问题或安全漏洞。 总的来说,通过 iptables 的应用,我们能够灵活地设置与管理服务器的防火墙规则,从而保护服务器免受各种网络攻击和恶意流量的侵害。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值