使用rave开发报表有两种方式:基于代码或采用可视报表设计器。
基于代码的报表
通过delphi平板代码编写报表,这是一种灵活的方式,该方式可以以各种复杂的方式来显示
任何一种数据。
为了编写基于代码的报表,仅仅放置一个TRvSystem部件在表单上,然后在OnPrint事件句柄
中写代码。Sender对象就是你正在创建的报表,它可以被类型强制转换为
TBaseReport。TBaseReport包含了你输出信息到特定报表中所需要的所有的方法。
简单的基于代码的报表
这里采用了基于代码编写简单报表。
procedure TFormMain.RvSystemPrint(Sender: TObject);
begin
with Sender as TBaseReport do
begin
SetFont('Arial', 15); //设定字体
GotoXY(1,1); //设定输出位置
//度量衡由SystemPrinter.Units决定,缺省为Inches
//也可通过SystemPrinter.UnitsFactor 来调整比例因子
Print('Welcome to Code Based Reporting in Rave'); //输出文字
end;
end;
为了执行代码获得报表,需要调用RvSystem.Execute方法。
采用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;
上面的代码对于每个文字的输出并没有使用坐标,而是使用了Lines和Columns作为参考。行
高是由当前使用的字体决定的。换行采用PrintLn或NewLine方法。列的输出位置是通过
SetTabs方法来设定,PrintTab方法将把文字输出到当前行的当前列。
图形的基于代码的报表
能够包括shapes和images在基于代码的报表中。如下代码示例:
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;
结论
基于代码的方式提供了一个非常灵活的设计方式来完成任意方式的报表,但是需要大量的工
作和精力来实现它。而采用可视报表设计器将采用一种非常容易的方式来完成报表。
Introduction to Rave Reports - Part I: Code Based Reports
Delphi 7 has included Rave Reports as the default reporting solution, replacing
Quick Reports. Since they work in very different paradigms, many people were
confused by the new environment. This is intended as an introduction for people
who haven't worked with Rave yet, and would like to start.
Delphi 7 ships with Rave Reports 5.0.8. If you haven't already, download the
update from the registered users page, since it fixes some important problems.
You can develop reports with Rave using two different ways: Code Based or with
the Visual Designer. This document.nbspdescribes how to work with the code
based engine. Part II will describe the Visual Designer.
Code Based Reports
With Code Based, you write reports using plain Delphi code. That provides a very
flexible way displaying any kind of data, allowing any kind of complex layouts.
To write a code based report, just drop a TRvSystem component on the form and
write the report on the OnPrint event handler. Sender is the report you are
creating, and can be typecasted to TBaseReport. It contains all the methods you
need to output information to that particular report.
Simple Code Base Report
Here's a simple report using the code based mechanism:
procedure TFormMain.RvSystemPrint(Sender: TObject);
begin
with Sender as TBaseReport do
begin
SetFont('Arial', 15);
GotoXY(1,1);
Print('Welcome to Code Based Reporting in Rave');
end;
end;
To execute this report, call RvSystem.Execute method.
So, what does that simple code do? First, it calls SetFont to select the font
and size of the text that will be printed from that point on. Then it positions
the cursor on the coordinates (1,1). These coordinates are expressed using the
units set in the SystemPrinter.Units property of the RvSystem object, and it
defaults to Inches. You can set it to unUser and set a number relative to Inches
in the SystemPrinter.UnitsFactor property. For example, if UnitsFactor was set
to 0.5 then 1 unit would correspond to half an inch. Finally, the code calls the
Print method to output the text. Here's the output:
Tabular Code Based Report
Here's another example. It displays a list of the folders in the root of the
current drive, along with a recursive count of number of files and folder, and
total size of the files included in each folder.
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;
SetTab(0.2, pjLeft, 1.7, 0, 0, 0);
SetTab(1.7, pjRight, 3.1, 0, 0, 0);
SetTab(3.1, pjRight, 3.5, 0, 0, 0);
SetTab(3.5, pjRight, 4.5, 0, 0, 0);
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;
Notice that a different approach has been taken: instead of specifying the
coordinates of each text output, the printing was done using Lines and Columns
as references. The line heigh depends on the size of the current font: each unit
represents 1/72nds of an inch, so each line printed with a size 10 font will
have, aproximatelly, a height of 0.138 inches. Lines are advanced after calls to
PrintLn or NewLine. Colums are defined using calls to the SetTabs method, and
the PrintTab method will print the text in the current column and advance to the
next one. Here's the output:
You can find the full source, including the implementation of EnumFolders and
GetFolderInfo, on CodeCentral.
Graphical Code Based Report
You can include shapes and images in your code based report, along with the
text. The following example demonstrates that:
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;
In this example the methods Rectangle, Ellipse and Pie have been used draw
shapes with different fills. Bitmaps were outputted using PrintBitmap and as the
brush of the ellipses. Here's the output:
A sample application, containing full source code for those three examples can
be found at CodeCentral.
Conclusion
As you can see, code based reporting offers a great flexibility and control of
the layout you want, but require some work to implement them. In Part II we will
see how the Visual Designer can be used to build powerful reports in a very easy
way.
{ A Code Based example of Rave Reports
by Leonel Togniolli - togniolli@uol.com.br
30/08/2003 }
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, RpDefine, RpBase, RpSystem, StdCtrls, ExtCtrls;
type
TFormMain = class(TForm)
RvSystem: TRvSystem;
Button1: TButton;
rgReport: TRadioGroup;
procedure RvSystemPrint(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
procedure GetFolderInfo(const Folder: string; var NumberOfFiles,
NumberOfFolders, SizeOfFiles: Cardinal);
procedure EnumFolders(Folders : TStrings; const Dir : string);
procedure PrintSimpleReport(Report : TBaseReport);
procedure PrintTabularReport(Report : TBaseReport);
procedure PrintGraphicsReport(Report : TBaseReport);
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
procedure TFormMain.RvSystemPrint(Sender: TObject);
begin
case rgReport.ItemIndex of
0 : PrintSimpleReport(Sender as TBaseReport);
1 : PrintTabularReport(Sender as TBaseReport);
2 : PrintGraphicsReport(Sender as TBaseReport);
end;
end;
procedure TFormMain.Button1Click(Sender: TObject);
begin
RvSystem.Execute;
end;
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;
SetTab(0.2, pjLeft, 1.7, 0, 0, 0);
SetTab(1.7, pjRight, 3.1, 0, 0, 0);
SetTab(3.1, pjRight, 3.5, 0, 0, 0);
SetTab(3.5, pjRight, 4.5, 0, 0, 0);
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.PrintSimpleReport(Report: TBaseReport);
begin
with Report do
begin
SetFont('Arial', 15);
GotoXY(1,1);
Print('Welcome to Code Based Reporting in Rave');
end;
end;
procedure TFormMain.EnumFolders(Folders: TStrings; const Dir: string);
var
sr : TSearchRec;
begin
if FindFirst(Dir+'*.*', faDirectory, sr) = 0 then
try
repeat
if (sr.Attr and faDirectory) = faDirectory then
Folders.Add(sr.Name);
until FindNext(sr) <> 0;
finally
FindClose(sr);
end;
end;
procedure TFormMain.GetFolderInfo(const Folder: string; var NumberOfFiles,
NumberOfFolders, SizeOfFiles : Cardinal);
var
sr : TSearchRec;
NFolders, NFiles, SFiles : Cardinal;
begin
NumberOfFolders := 0;
NumberOfFiles := 0;
SizeOfFiles := 0;
if FindFirst(Folder+'*.*', faAnyFile, sr) = 0 then
try
repeat
if (sr.Attr and faDirectory) <> faDirectory then
begin
Inc(NumberOfFiles);
Inc(SizeOfFiles, Cardinal(sr.Size));
end
else if not SameText(sr.Name, '.') and not SameText(sr.Name,'..') then
begin
Inc(NumberOfFolders);
GetFolderInfo(IncludeTrailingPathDelimiter(Folder+sr.Name), NFolders,
NFiles, SFiles);
Inc(NumberOfFiles, NFiles);
Inc(NumberOfFolders, NFolders);
Inc(SizeOfFiles, SFiles);
end;
until FindNext(sr) <> 0;
finally
FindClose(sr);
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;
end.