rave 补充
在国内,大凡介绍工具的书总是浅尝即止,对于rave也是如此!
在《delphi7经典组件解析》一书中,用了3章来介绍rave。虽然,说明了rave面板上的控件怎么用,怎么设计报表,可是最关键的如何操纵报表,却一字未提,这不能不说是 失败! 因为在实际应用中,往往报表上的内容是动态变化,而不是千篇一律的,如果无法操作报表内的控件,那么就要制作数量众多的报表,这是开发人员无法忍受的! 这里,就自己使用rave的一些经验说明如何操纵rave的报表。
rave报表的设计,大致可以分为3种:
第一,打开rave的设计器,然后根据需求设计(包括:各种数据字段、非数据字段、数据来源的链接等)好,当程序运行的时候导入报表,进行打印或显示或存为文件;
第二,直接在代码里操纵报表,报表的内容全部用代码来控制;
第三,先使用rave设计器制作若干个模板,然后在程序运行的时候通过代码来控制模板上各种数据的打印值。
从这三种说明可以看出,第一种是最死板的,也是“骗钱”的书最爱介绍的;第二种是最灵活的,但是难度比较大,因为对各种数据的显示位置要了如指掌,不允许出现各种差错,比较难掌握;第三种,属于折中方案,当各种报表的格式比较一致时这种方法会比较合适。
下面,首先说明如何使用第三种方案,最后在简要介绍一下第二种方案。
由于项目的需要,要制作几张报表,报表的格式是已知的,而且格式也比较一致,只是显示的数据不一样。鉴于这样的需求,我设计了一个模板报表文件:template.rav。
接着,rave面板上最重要的两个控件登场了:RvProject和RvSystem:RvProject是用来操纵报表的,而RvSystem则可以控制打印的格式:预览阿,打印设置阿等等。接下来就可以开始编码了:
......这里省略了rvProject的创建过程
rvProject.ProjectFile :=ExtractFilePath(Application.ExeName)+ 'template.rav';
rvProject.Open;
With rvProject.ProjMan do
begin
end;
这是通常的操纵报表的格式。
要如何来操纵报表的数据呢? 主要是使用FindRaveComponent 函数,在说明之前,先看看delphi7的rave包里有哪些单元,各单元都包括了哪些数据类 :(如果不uses 这样单元的话,就无法定义和操作对应的数据对象了,所以这个很重要)
RvCsStd :TRaveText,TRaveMemo,TRaveSection,TRaveSection,TRaveMetaFile,
TRaveFontMaster,TRavePageNumInit
RvClass:TRaveComponent,TRaveControl, TRaveContainerControl,
TRaveContainerComponent,TRaveProjectItem,TRavePage
RvCsData:TRaveDataText,TRaveDataMemo,TRaveCalcText,
TRaveDataMirrorSection,TRaveDataCycle, TRaveCalcOp,TRaveCalcTotal,TRaveCalcController
RvCsBars: TRavePostNetBarCode,TRaveI2of5BarCode,TRaveCode39BarCode,TRaveCode128BarCode,
TRaveUPCBarCode,TRaveEANBarCode
RvCsDraw: TRaveLine,TRaveHLine,TRaveVLine,TRaveRectangle,
TRaveSquare,TRaveEllipse, TRaveCircle
RvDataField: TRaveStringField,TRaveIntegerField,
TRaveBooleanField,TRaveFloatField,TRaveCurrencyField,TRaveBCDField,
TRaveDateField,TRaveTimeField,TRaveDateTimeField,TRaveBlobField,
TRaveMemoField,TRaveGraphicField,TRaveInt64Field
RvDatabase: TRaveDatabase
RvDirectDataView: TRaveDataView,TRaveDriverDataView
RvProj:TRaveReport,TRaveProjectManager
RvSecurity:TRaveSimpleSecurity,TRaveLookupSecurity
RvCsRpt:TRaveRegion,TRaveBand,TRaveDataBand,TRaveIterateBand,
TRaveBandStyle,TRaveDataCycle,
这么多,看得快晕了吧! 其实,并没有必要全部看懂,当我们用到某个数据类,再来查一下就可以了。 下面开始说怎么使用FindRaveComponent 函数。这个函数的使用非常简单,在如下示例中:
var MyHeadBand: TRaveBand;
MyHeadBand := FindRaveComponent('BandHead',MyPage) as TRaveBand;
先定义了一个TRaveBand对象,然后在MyPage中查找以'BandHead'命名的Band对象然后赋给MyHeadBand 。
下面给个简单的例子:
rvProject :=TRvProject.Create(self);
rvSystem :=TRvSystem.Create(nil);
rvProject.Engine :=rvSystem;
//-----设置预览的属性---------//
rvSystem.SystemSetups :=rvSystem.SystemSetups -
[ssAllowSetup, ssAllowDestPreview, ssAllowDestPrinter, ssAllowPrinterSetup,ssAllowDestFile];
if ( Sender as TComponent).Tag =0 then
begin
rvSystem.DefaultDest :=rdPreview;
rvSystem.SystemSetups :=rvSystem.SystemSetups -[ssAllowDestPreview];
end
else if ( Sender as TComponent).Tag =1 then
begin
rvSystem.DefaultDest :=rdPrinter;
rvSystem.SystemSetups :=rvSystem.SystemSetups +[ssAllowSetup, ssAllowDestPrinter, ssAllowPrinterSetup];
end;
//-----设置预览页面的格式---------//
rvSystem.SystemFiler.StatusFormat := '正在生成第%p页...';
rvSystem.SystemPreview.FormState := wsMaximized;
rvSystem.SystemPrinter.StatusFormat := '正在打印第%p页...';
rvSystem.SystemPrinter.Title := SchoolName+ '消费系统数据报表';
rvSystem.TitleSetup := '输出设置';
rvSystem.TitlePreview := SchoolName+ '消费系统数据报表';
rvSystem.TitleStatus := '报表状态';
//-----初始化rvProject---------//
rvProject.ProjectFile :=ExtractFilePath(Application.ExeName)+ 'template.rav';
rvProject.Open;
With rvProject.ProjMan do
begin
MyPage := FindRaveComponent('Report1.Page',nil) as TRavePage; //获得上面所
//打开的template.rav报表文件中'Report1报表的page页面;
MyRegion:= FindRaveComponent('RegionBG',MyPage) as TRaveRegion;
//获得page页面上的以'RegionBG'命名的区域
MyDataView :=FindRaveComponent('DataView',nil) as TraveDataView;
//获得template.rav报表文件以'DataView'命名的数据视图
MyDataView.ConnectionName :=RvDataSetConnection.Name;//将该视图链接到程序上的某个
//RvDataSetConnection对象
MyHeadBand := FindRaveComponent('BandHead',MyPage) as TRaveBand;
//以下代码是设置page页面上的以Title命名的Text的字体
MyText:=FindRaveComponent('Title', MyPage) as TRaveText;
MyText.Font.Size :=20; //设置字体的属性
MyText.Font.Color :=ClBlack;
MyText.Font.Name :='宋体';
//以下代码是设置page页面上的以'DataDates'命名的数据字段的属性
MyDataText:=FindRaveComponent('DataDates', MyPage) as TRaveDataText;
MyDataText.DataView :=MyDataView;
MyDataText.DataField :='DateTimes';
end;
rvProject.Execute; //进行预览
rvProject.Close; //关闭
需要做特殊说明的是:
查找page,dataview后面的parent引用的是nil,而其他的页面上的对象引用时用page,象:
MyText:=FindRaveComponent('Title', MyPage) as TRaveText;
至于第二种方案的操作方式是这样子的:
采用TAB方式的基于代码的报表:
procedure TFormMain.PrintTabularReport(Report: TBaseReport);
var
FolderList : TStringList;
i : Integer;
NumFiles : Cardinal;
NumFolders : Cardinal;
SizeFiles : Cardinal;
Root : string;
begin
with Report do
begin
SetFont('Arial', 15); //设定字体
NewLine; //换行
PrintCenter('List of Folders in the Drive Root', 4); //输出文字
NewLine; //换行
NewLine; //换行
ClearTabs; //清楚以前Tab的定义
SetTab(0.2, pjLeft, 1.7, 0, 0, 0); //定义Tab的宽度
SetTab(1.7, pjRight, 3.1, 0, 0, 0); //定义Tab的宽度
SetTab(3.1, pjRight, 3.5, 0, 0, 0); //定义Tab的宽度
SetTab(3.5, pjRight, 4.5, 0, 0, 0); //定义Tab的宽度
SetFont('Arial', 10); //设定字体
Bold := True; //设定为粗体
PrintTab('Folder Name'); //输出文字
PrintTab('Number of Files'); //输出文字
PrintTab('Number of Folders'); //输出文字
PrintTab('Size of Files'); //输出文字
Bold := False; //取消粗体
NewLine; //换行
FolderList := TStringList.Create;
try
Root := IncludeTrailingPathDelimiter(ExtractFileDrive(ParamStr(0))); //获得驱动
器号
EnumFolders(FolderList, Root); //枚举出文件和路径信息
for i := 0 to FolderList.Count - 1 do
begin
PrintTab(FolderList[i]); //输出文字
GetFolderInfo(IncludeTrailingPathDelimiter(Root+FolderList[i]),
NumFiles, NumFolders, SizeFiles);
PrintTab(Format('%u',[NumFiles])); //输出文字
PrintTab(Format('%u',[NumFolders])); //输出文字
PrintTab(Format('%u bytes',[SizeFiles])); //输出文字
NewLine;
end;
finally
FolderList.Free;
end;
end;
end;
图形的基于代码的报表
procedure TFormMain.PrintGraphicsReport(Report: TBaseReport);
var
Bitmap : TBitmap;
begin
with Report do
begin
Canvas.Brush.Color := clGray; //设定填充色
Rectangle(0.3, 0.3, 4.7, 3.3); //绘制矩形
SetFont('Arial', 15); //设定字体
FontColor := clRed; //设定文字颜色
PrintXY(0.5,0.5, 'Just look at all the graphics!'); //在特定位置输出文字
Bitmap := TBitmap.Create; //创建位图对象
try
Bitmap.LoadFromFile('delphi.bmp'); //装载位图
PrintBitmap(3.5,0.3,1,1, Bitmap); //在特定位置输出位图
PrintBitmap(1,2,3,3, Bitmap); //在特定位置输出位图
Canvas.Pen.Color := clBlue; //设定轮廓线的颜色
Canvas.Brush.Bitmap := Bitmap; //设定填充图案
Ellipse(5,0.3,6,3.3); //在特定位置绘制椭圆
Ellipse(2,1,4,1.9); //在特定位置绘制椭圆
finally
Bitmap.Free; //释放位图对象
end;
Canvas.Pen.Color := clBlack; //设定轮廓线的颜色
Canvas.Brush.Style := bsSolid; //设定填充线类型
Canvas.Brush.Color := clYellow; //设定填充线颜色
Pie(0.7,0.7,1.7,1.7,1,1,1,2); //绘制饼图
Canvas.Brush.Color := clGreen; //设定填充线颜色
Pie(0.7,0.7,1.7,1.7,1,2,1,1); //绘制饼图
end;
end;
至此,还算有点实用价值的rave介绍就结束了,rave中应该还包括更多需要探讨的功能,这里只起个抛砖引玉的作用!
附:参考了《rave报表开发指南1.0》和大富翁论坛中jiangguan同志的笔记
浙公网安备 33010602011771号