如何用Delphi語言制作中國式的報表

字號:

在數(shù)據(jù)庫應(yīng)用程序開發(fā)中,系統(tǒng)設(shè)計員、程序設(shè)計員需要考慮的一個重要問題是如何設(shè)計和輸出報表,在Delphi中我們可以采用多種方案來解決這一問題。如運(yùn)用OLE自動化技術(shù)將數(shù)據(jù)輸出到MS-Word、MS-Excel中等,但其中最直接、最本地化的還是使用Delphi3.0/40中的QuickReport報表組件。它是挪威QuSoft公司專門為Delphi 編寫的,使QuickReport可以迅速設(shè)計出符合西方人習(xí)慣用的報表。
    然而,在設(shè)計中國式報表時,筆者發(fā)現(xiàn)在QuickReport中設(shè)計列與列之間的豎線和斜線比較困難;雖然QuickReport提供了TQShape控件,使用該控件可以畫出列與列之間的豎線,但如果用戶不能正確地調(diào)整TQShape實例的高度,輸出報表的豎線不是不連續(xù)就是超長,另外如果我們調(diào)整了某個Band的高度,我們將不得不調(diào)整該Band下的所有TQShape實例的高度;至于斜線,QuickReport報表組件根本就沒有提供這一功能。
    筆者認(rèn)真查找了有關(guān)的資料,成功地解決了以上問題,希望能對大家有所幫助。
    解決思路
    以TQShape為父類,建立新的控件,新控件可以畫豎線、斜線和反斜線。重載TQShape 類的Paint方法,這樣在設(shè)計階段可以非常直觀地畫堅線、斜線和反斜線。用戶可以在設(shè)計階段選擇線的類型,如果選擇直線,控件自動將其高度調(diào)整為所屬Band的高度,用戶可以調(diào)整其橫向位置但不能調(diào)整其高度;如果選擇斜線,用戶可以根據(jù)需要調(diào)整斜線的長度和傾角。
    重載TQShape 類的Print方法,這樣可以在運(yùn)行階段輸出直線和斜線。說明:該控件只能畫直線和斜線,如果讀者需要畫矩形和圓,可以使用TQShape控件來實現(xiàn)。
    控件設(shè)計步驟
    步驟1.使用Delphi提供的控件向?qū)?選擇TQShape為父類,建立新類TMyQRShape,并選擇適當(dāng)?shù)陌?Package),最后生成單元文件。
    步驟2.在生成的單元文件中,增加枚舉類型。
    TLines = ( None,ToPBottom,BottomTop ) None、TopBottom、BottomTop三種取值,分別代表直線、斜線 \ 和反斜線 /。
    步驟3.在新類TMyQRShape 中增加private 成員 FLineType:TLines ,增加published屬性 LineType:TLines Read
    FLineType Write SetFLineType。
    步驟4.建立過程SetFLineType。
    procedureTMyQRShape.SetFLineType(value:TLines);beginif value<>FLineType thenbeginFLineType:=value Invalidate end end
    步驟5.重載Paint方法。
    procedure TMyQRShape.Paint begincase LineType ofBottomTop:beginCanvas.MoveTo(0,Height) Canvas.LineTo(width,0 ) end ToPBottom:beginCanvas.MoveTo(0,0) Canvas.LineTo(width,Height ) end None:beginHeight := Parent.Height Top:=0 Width:=4 Shape:=qrsVertLine Inherited Paint end end end
    步驟6.重載Print方法。
    procedure TMyQRShape.Print(OfsX,OfsY : Integer);beginwith QRPrinter dobegincase LineType ofBottomTop:beginCanvas.MoveTo(XPos(OfsX + Size.Left), YPos(OfsY + Size.Top)+Height) Canvas.LineTo(XPos(OfsX + Size.Left)+width,YPos(OfsY + Size.Top) ) end TopBottom:beginCanvas.MoveTo(XPos(OfsX + Size.Left), YPos(OfsY + Size.Top)) Canvas.LineTo(XPos(OfsX + Size.Left)+Width,YPos(OfsY + Size.Top)+Height ) end None:Inherited Print(OfsX,OfsY ) end end end;