Delphi报表制作技巧 目 录 Delphi 3中报表的制作................................................................................................................................................ 2 Delphi编写一个打印程序, ........................................................................................................................................ 3 Delphi应用程序中中国式报表的制作........................................................................................................................... 3 打印测试................................................................................................................................................................... 6 Quick Report 2.0 ......................................................................................................................................................... 7 quickreport................................................................................................................................................................10 把查询信息输出到word打印 .....................................................................................................................................11 财务报表..................................................................................................................................................................12 格式化整数输出。 ....................................................................................................................................................15 Delphi编写一个打印程序 ..........................................................................................................................................16 打印功能的实现........................................................................................................................................................17 动态制作报表 ...........................................................................................................................................................19 多栏打印..................................................................................................................................................................20 检测存在打印机........................................................................................................................................................20 精确打印输出的程序实现 ..........................................................................................................................................21 Delphi应用程序中中国式报表的制作..........................................................................................................................23 用Delphi编写打印程序的窍门 ...................................................................................................................................26 用Delphi实现打印功能 .............................................................................................................................................26 网络远程报表 ...........................................................................................................................................................27 中国式报表 ..............................................................................................................................................................29 Delphi 3中报表的制作 Borland Delphi是当今优秀的Windows可视化开发工具之一,今年5月份推出的Delphi3是一个真正的32位开发平台,比Delphi2增加了不少定制控件。Delphi 3没有捆绑ReportSmith报表制作工具,但同时增加了Qreport组中报表制作控件的功能,使制作报表更加方便灵活。在Delphi3中除了可以采用Qreport组中报表制作控件来制作报表外,还可利用打印机画布直接向打印机输出报表。下面将详细介绍这两种方法。 用打印机画布制作报表 Delphi引进了画布的概念,使向打印机输出和向屏幕的输出具有相同的方法,直接向打印机的画布输出线条和字符串,即可制作出任意规格的报表。首先,把支持打印机的Printers单元手工加到uses域里,然后在打印事件中调用Tprinter对象来制作报表。下面我们来看一个实际例子。假设在当前Form1上有一按钮名为Print-rep;在Dialogs控件组选取一PrintDialog控件加到Form1中,命名为printdg1;在Additional控件组中选取一StringGrid控件加到Form1中,命名为temsgrid1,设其网格为10行10列,并假设已完成了在temsgrid1控件中显示一10行10列的数据库表数据的准备工作,然后在Print—repClick事件中打印报表。程序示例如下: procedure TForm1.Print-repClick(Sender:Tobject); var I,j,cp,ph,pw,w,h:integer; beginif printdg1.Execute then //打开打印对话框 begin for cp:=1 to printdg1.copies do //打印份数 begin with printer do begin orientation:=poPortrait; //设置纵向打印方式 title:=‘打印报表例子’;//打印任务标题 pw:=pagewidth;//获得当前设置的打印纸页宽 ph:=pageheight; //获得当前设置的打印纸页高 h:=2104; w:=1488; begindoc;//开始打印 //下面画表格,先画11条横线 for I:=1 to 11 do begin canvas.moveto(100*pw div w,I*100*ph div h); canvas.lineto(1100*pw div w,I*100*ph div h); end; //再画11条竖线 for I:=1 to 11 do begin canvas.moveto(I*100*pw div w,100*phdiv h); canvas.lineto(I*100*pw div w,1100*ph div h); end; //填上数据 for j:=1 to 10 do for I:=1 to 10 do canvas.textout((100*I+10)*pwdiv w,(100*j+10)*ph div h,temsgrid1.cells[I -1,j-1]); enddoc;//结束打印 end; end; end; end; 在上面程序中,先打开打印对话框,然后再设置打印方向、打印标题并获取当前打印纸的宽高点数。在程序中,为了使在不同打印分辨率中有相同的打印外观,我们以180×180分辨率的A4纸点数2104×1488做为基准换算打印坐标。Printer.Canvas.Moveto(x,y)用于移动打印机画布坐标到(x,y)处;Printer.Canvas.Lineto(x,y)用于从画布当前坐标处画一直线至(x,y);Printer.Canvas.Textout(x,y,Text)用于在画布的坐标(x,y)处以当前字体输出字符串 Text。为了使报表更加美观和生动,可以设置打印机画布的字体、大小,还可以插入图片等。 用Qreport组控件制作报表 QuickReport是Quick Soft Development公司专为Delphi设计的用于制作报表的工具。 Delphi3中Qreport组控件十分丰富,只要很好地利用这些控件就能制作出效果不错的报表来。 1.建立一个报表 (1)首先我们在Form2上放置一TQuickRep控件,TQuickRep控件是建立一报表必不可少的控件。可以改变该控件的属性设置,以使其外观符合要求。在缺省情况下,TQuickRep控件的尺寸为放置在窗口上的尺寸,TQuickRep控件根据当前控件的尺寸来自动设置数据区的范围。 改变TQuickRep控件外观最简单的方法是:在TQuickRep控件内单击鼠标右键,在弹出菜单中选择Report Settings项来
2
打开设置窗口。 (2)设置数据。把TQRBand控件放到TQuickRep控件上,并把BandType属性设为rbTitle,缺省情况下Align属性是a1Top。然后把TQRLabel控件放到TQRBand控件上,修改它的Caption属性,作为报表的标题。 (3)把数据放到报表上。首先再将一个TQRBand控件放到TQuickRep控件上,并把BandType属性设为rbDetail,然后把一个Ttable控件(名为Table1)放到From2上,设置它的DataBaseN ame属性和TableName属性,并把Ttable控件的Active属性设为True。与Delphi2不同的是,Delphi3中TQuickRep控件没有DataSource属性而以DataSet属性来代替,因此设置TQuickRep控件的DataSet属性值为Table1。 (4)把一个TQRDBText控件放到第二个TQRBand控件上,设置它的DataSet属性值为Table1,设置DataField属性为要显示的字段。 到此,就可在TQuickRep内单击鼠标右键,在弹出菜单中选择Review项来预览报表。 2.预览及打印报表 在运行期间也可以调用TQuickRep的Preview方法来预览报表,在预览窗口中可单击打印按钮来打印报表,但也可直接调用TQuickRep的Print方法来打印报表。 3.给报表的数据画上网格 在省缺情况下,报表的数据周围是没有网格的。我们可以给数据周围加上网格,使其看起来更像一个表格,方法是设置TQRBand控件的高度与TQRDBText高度控件相同,将所有的TQRDBText控件的AutoSize属性设为False,并将它们首尾相连,然后将每一个TQRDBText控件的Frame的子属性DrawBottom、DrawLeft、DrawRight、DrawTop设为True,子属性Style设为poSolid。这样即可加上网格线。 Qreport控件组共有16种报表制作工作,以上只是一个粗略的介绍,不能尽述其强大的功能。在具体应用中,用户可以通过加载其它报表制作控件设计出有个性的报表来。 两种方法的比较 以上两种制作报表的方法各有千秋。用Qreport组控件来制作报表的方法比较简单,但是当报表较多时,用此方法显得较笨拙,并且使编译后的可执行文件急剧增大。用打印机画布制作报表的方法比较繁重,必须根据实际的报表来设计每一条线的起止坐标,算好每个坐标点的值,但当报表较多时,用此方法显得较灵活,并且使编译后的可执行文件的代码量增加不多,因此在这种情况下建议选用此方法 Delphi编写一个打印程序, 如果你想自己用那么,下面这些技巧或许对你有所帮助。 1.获娶显示当前打印机的分辨率 Windows下的打印分辨对打印程序有着至关重要的作用,如果你想知道打印机的分辨率,请在程序中加入一行:ShowMessage(′水平分辨率′+inttostr(GetDeviceCaps(printer?Handle,LOGPIXELSX))+chr(13)+′垂直分辨率:′+inttostr(GetDeviceCaps(printer?Handle,LOGPIXELSY)));结果就一目了然了。 2.将结果直接送到打印机 Delphi提供了两种打印方式:一是将结果输送到Form,再调用Form的print方法将结果输送到打印机,二是将结果直接输送到打印机。如果你采用第一种方式,则无论你怎样调整Form的PrintScal属性,打印出来的东西也不会让你满意。因此建议采用第二种方式。 3.尽量不要使用AssignPrn 尽管AssignPrn简化了文本打印操作,使输出到打印机像输出到文件一样简单。但简单带来的是一系列的不方便:你无法知道当前打印的行数,无法准确控制行距,无法灵活改变字体字形等等。还是用打印机的Canvas属性进行打印吧。 4.用打印机的点数做度量单位 如果想让打印程序在任何打印机上都能正常地打印,你就必须改变你的度量单位。如果采用固定的度量,不同分辨率的打印效果是不同的。举例来讲:printer?Canvas?rectangle(0,0,360,720)在360×360的佳能4200SP上能打出一个1英寸宽、2英寸高的矩形,但在600×600的惠普6L上只能打出0?6英寸宽、1?2英寸高的矩形。使用打印机的点 数做为度量单位是一个明智的选择。具体做法如下: VarPointX,PointY:integer;PointX:=GetDeviceCaps(printer? Handle,LOGPIXELSX);PointY:=GetDeviceCaps(printer?Handle,LOGPIXELSX);printer? Canvas?rectangle(0,0,PointX*1,PointY*2)这样,无论你使用什么样的打印机,都能得到一个1英寸宽、2英寸高的矩形。 5.添加打印程序单元 尽管Delphi在生成窗体时会自动在USES部分加入许多程序单元,但打印程序单元(Printers) 却不在之列,要想使打印机正常工作和程序不出错,你还是老老实实手工给它加上吧。 Delphi应用程序中中国式报表的制作 在众多可视化数据库开发工具中, Delphi以其真正的面向对象、高效率、支持多层结构应用开发、支持多层B/S结构开发等优良特性脱颖而出,成为广大编程人员的首选开发工具。
3
在数据库应用程序开发中,系统设计员、程序设计员需要考虑的一个重要问题是如何设计和输出报表,在Delphi中我们可以采用多种方案来解决这一问题,如运用OLE自动化技术将数据输出到MS-WORD、MS-EXCEL中等,但其中最直接、最本地化的还是使用Delphi3.0/40中的QuickReport报表组件,它是挪威QuSoft公司专门为Delphi 编写的,使用QuickReport可以迅速设计出符合西方人习惯的报表。 然而,在设计中国式报表时,笔者发现在QuickReport中设计列与列之间的竖线和斜线比较困难;虽然QuickReport提供了TQShape控件,使用该控件可以画出列与列之间的竖线,但如果用户不能正确调整TQShape实例的高度,输出报表中的竖线不是不连续就是超长,另外如果我们调整了某个Band的高度,我们将不得不调整该Band下的所有TQShape实例的高度;至于斜线,QuickReport报表组件根本就没有提供这一功能。 笔者认真查找了有关资料,成功地解决以上问题,并愿意将解决方法与大家共享,希望能对大家有所帮助。 1、 解决思路 以TQShape为父类,建立新的控件,新控件可以画竖线、斜线和反斜线。重载TQShape类的Paint方法,这样在设计阶段可以非常直观地画斜线、反斜线和竖线,用户可以在设计阶段选择线的类型,如果选择直线,控件自动将其高度调整为所属Band的高度,用户可以调整其横向位置但不能调整其高度;如果选择斜线,用户可以根据需要调整斜线的长度和倾角。重载TQShape类的Print方法,这样可以在运行阶段输出直线和斜线。 说明:该控件只能画直线和斜线,如果读者需要画矩形和园,可以使用TQShape控件来实现。 2、控件设计步骤 步骤1、使用Delphi提供的控件向导,选择TQShape为父类,建立新类TMyQRShape,并选择适当的包(Package),最后生成单元文件。 步骤2、在生成的单元文件中,增加枚举类型, Tlines = ( None,TopBottom,BottomTop ) ; None、TopBottom、BottomTop三种取值,分别代表直线、斜线 和反斜线 / 。 步骤3、在新类TMyQRShape 中增加private 成员 FLineType:Tlines ,增加published属性 LineType:Tlines Read FLineType Write SetFLineType 。 步骤4、建立过程SetFLineType 。 procedure TMyQRShape.SetFLineType(Value:Tlines); begin if Value<>FLineType then begin FLineType:=Value ; Invalidate ; end ; end ; 步骤5、重载Paint方法 procedure TMyQRShape.Paint ; begin case LineType of BottomTop: begin Canvas.MoveTo(0,Height) ; Canvas.LineTo(width,0 ) ; end ; TopBottom: begin Canvas.MoveTo(0,0) ; Canvas.LineTo(width,Height ) ; end ; None: begin Height := Parent.Height ; Top:=0 ; Width:=4 ; Shape:=qrsVertLine ; Inherited Paint ; end ; end ; end ; 步骤6、重载Print方法 procedure TMyQRShape.Print(OfsX,OfsY : Integer); begin with QRPrinter do begin case LineType of BottomTop:
4
begin Canvas.MoveTo(Xpos(OfsX + Size.Left), Ypos(OfsY + Size.Top)+Height) Canvas.LineTo(Xpos(OfsX + Size.Left)+width,Ypos(OfsY + Size.Top) ) ; end ; TopBottom: begin Canvas.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; 步骤7、保存并安装TMyQRShape控件。 本控件在Delphi40下调试、安装,并成功应用于某数据库管理系统的开发。该控件的完整代码如下。 源程序: unit MyQRShape; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, QuickRpt, Qrctrls; type Tlines = ( None,TopBottom,BottomTop ) ; TMyQRShape = class(TQRShape) private FLineType:Tlines ; procedure SetFLineType(Value:Tlines) ; protected procedure Print(OfsX, OfsY : integer); override; procedure Paint ;Override ; public published property LineType:Tlines Read FLineType Write SetFLineType ; end; procedure Register; implementation procedure TMyQRShape.SetFLineType(Value:Tlines); begin if Value<>FLineType then begin FLineType:=Value ; Invalidate ; end ; end ; procedure TMyQRShape.Paint ; begin case LineType of BottomTop: begin Canvas.MoveTo(0,Height) ; Canvas.LineTo(width,0 ) ; end ; TopBottom: begin Canvas.MoveTo(0,0) ; Canvas.LineTo(width,Height ) ; end ; None: begin
5