關於WEB應用程式的列印元件開發初探 (轉)

worldblog發表於2007-12-03
關於WEB應用程式的列印元件開發初探 (轉)[@more@] 

一、引言:namespace prefix = o ns = "urn:schemas--com::office" />

  近些年來,隨著網際網路的普及和推廣,傳統的單機和局域中的C/S模式的應用越來越不能滿足資訊共享的要求。因此,一種新的基於的B/S的應用程式的開發方式被提了出來。新的開發方案以其客戶端的免維護、免、程式能根據的資訊能夠自動升級;伺服器端多層模式的應有提高處理的和性越來越被廣大的應用程式的開發者所看好。成為應用程式開發的一個新的發展方向。在的平臺上,人們利用來開發服務的顯示介面,而用來封裝商業規則,在各種雜誌上利用各種工具進行元件開發也是屢見不鮮。但介紹列印組開發卻不怎麼看到。筆者希望就自已開發列印元件的一點心得體會來拋磚引玉。

 

二、設想

  列印元件要求是在一次為某單位開發資訊管理中被提及的,這個系統中的一些票據需要列印。這樣,如何對這些票據進行套打成了我們必須解決的問題。

  要在客戶端列印一些要求的票據或其它的文字或圖片資料,有兩種方式:一種是利用的ACTIVE FORM來生成客戶端的介面,由瀏覽器,並在客戶端執行。(這種方式在開發多後臺中,較為常用。在國內許多新版本的財務都採用了這種方法,其缺點是對開發人員的要求太高),另一種是開發一個元件在客戶端安裝,然後,由伺服器端來生成指令碼,在客戶端執行、建立相應的元件;利用元件物件來進行列印操作。(這種方法只要客戶端的COM元件開發完成,使用者只要熟悉VBSCRIPT或script指令碼語言就可能方便的)。本文我們主要討論第二種方式。

 

三、實現

  首先、執行DELPHI 5.0;選擇FILE選單中的NEW,在彈出的對話方塊中選擇頁,選擇ActiveX Library建立ActiveX庫.然後,再往新建的庫中加入一個Automation ,操作步驟同上。在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: WString; 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結束列印任務。

<!--

 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()

//--&gt

 

五、程式碼解析

  在這個元件中,我們所要解決的幾個問題:

(1)、在Delphi的應用中自定義列印紙張的設定,Delphi中自身帶了一個QuickReport的列印設計程式,這個程式在一定的程度上方便了列印的設計,但這個設計程式對於自定義紙張的設定和列印支援卻不是很好。因此,在這個元件中我們採用手工程式碼來設定自定義紙張大小。

Function TPrtTest3.InitPrintPaper:Boolean;

Var

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

  :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^.dmPaength:= 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的指令碼程式。

源程式請到程式設計師雜誌頻道下載.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-987733/,如需轉載,請註明出處,否則將追究法律責任。

相關文章