FastReport VCL程序员手册:如何借助代码构建报告
修改报告页面的属性
FastReport VCL是用于Delphi,C ++ Builder,RAD Studio和Lazarus的报告和文档创建VCL库。它提供了可视化模板设计器,可以访问为30多种格式,并可以部署到云,网站,电子邮件和打印中。
近日,FastReport VCL更新至v6.9,在新版本中,在PDF更新中增加了对以下对象的并行表单支持:文本,替换和图片。能够通过InteractiveForms字体子集属性将所需的字形仅包含在相互之间形式中。同时修复了多个Bug问题。欢迎下载体验。(旁边向下按钮下载)
FastReport VCL试用版免费下载【慧都网】
有时有必要从代码中修改报告页面设置(例如,修改纸张对齐方式或尺寸)。本TfrxReportPage类包含以下属性,定义页面的大小:
property Orientation: TPrinterOrientation default poPortrait; property PaperWidth: Extended; property PaperHeight: Extended; property PaperSize: Integer;
该PaperSize属性设置纸张格式。这是Windows.pas中定义的标准值之一(例如DMPAPER_A4)。如果为此属性分配了一个值,则FastReport会自动填充PaperWidth和PaperHeight属性(纸张尺寸以毫米为单位)。将DMPAPER_USER(或256)值设置为格式,将意味着已设置自定义纸张尺寸。在这种情况下,PaperWidth和PaperHeight属性应手动填写。
以下示例显示了如何修改第一页的参数(假设我们已经有一个报告):
Pascal:
var Page: TfrxReportPage; { the first report’s page has [1] index. [0] is the Data page. } Page := TfrxReportPage(frxReport1.Pages[1]); { modify the size } Page.PaperSize := DMPAPER_A2; { modify the paper orientation } Page.Orientation := poLandscape;
C ++:
TfrxReportPage * Page; // the first report’s page has [1] index. [0] is the Data page. Page = (TfrxReportPage *)frxReport1.Pages[1]; // modify the size Page->PaperSize = DMPAPER_A2; // modify the paper orientation Page->Orientation = poLandscape;
借助代码构建报告
FastReport引擎通常负责报表的构建。它以特定顺序显示报告的频段,次数与报告所连接的数据源所需的次数相同,因此形成了完整的报告。有时有必要创建非标准格式的报告,而FastReport引擎无法生成该报告。在这种情况下,可以借助TfrxReport.OnManualBuild事件来手动构建报告的功能。如果要定义此事件的处理程序,则FastReport引擎将管理发送给该事件。同时,以以下方式更改了形成报告的职责分配:
FastReport引擎:
- 报告的准备(脚本,数据源初始化,乐队的树形结构)
- 所有计算(聚合函数,事件处理程序)
- 新页面/列的形成(自动显示页面/列的页眉/页脚,报告标题/摘要)
- 其他日常工作
处理程序:
- bands的演出按一定顺序
OnManualBuild处理程序的本质是发出有关将某些频段呈现给FastReport引擎的命令。引擎本身将完成剩下的工作:只要当前页面中没有位置,就会创建一个新页面。脚本将被执行。
引擎由TfrxCustomEngine类表示。此类的实例的链接位于该TfrxReport.Engine属性中。
让我们举一个简单的处理程序的例子。报告中有两个“主数据”带,它们未连接到数据。处理程序以隔行顺序呈现这些频段,每个频段六次。在六个频段之后,会出现一个很小的间隙。
Pascal:
var i: Integer; Band1, Band2: TfrxMasterData; { find required bands } Band1 := frxReport1.FindObject('MasterData1') as TfrxMasterData; Band2 := frxReport1.FindObject('MasterData2') as TfrxMasterData; for i := 1 to 6 do begin { lead/deduce bands one after another } frxReport1.Engine.ShowBand(Band1); frxReport1.Engine.ShowBand(Band2); { make a small gap } if i = 3 then frxReport1.Engine.CurY := frxReport1.Engine.CurY + 10; end;
C ++:
int i; TfrxMasterData * Band1; TfrxMasterData * Band2; // find required bands Band1 := dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData1")); Band2 := dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData2")); for(i = 1; i <= 6; i++) { // lead/deduce bands one after another frxReport1->Engine->ShowBand(Band1); frxReport1->Engine->ShowBand(Band2); // make a small gap if(i == 3) frxReport1->Engine->CurY += 10; }
下一个示例显示两组bands并排放置。
Pascal:
var i, j: Integer; Band1, Band2: TfrxMasterData; SaveY: Extended; Band1 := frxReport1.FindObject('MasterData1') as TfrxMasterData; Band2 := frxReport1.FindObject('MasterData2') as TfrxMasterData; SaveY := frxReport1.Engine.CurY; for j := 1 to 2 do begin for i := 1 to 6 do begin frxReport1.Engine.ShowBand(Band1); frxReport1.Engine.ShowBand(Band2); if i = 3 then frxReport1.Engine.CurY := frxReport1.Engine.CurY + 10; end; frxReport1.Engine.CurY := SaveY; frxReport1.Engine.CurX := frxReport1.Engine.CurX + 200; end;
C ++:
int i, j; TfrxMasterData * Band1; TfrxMasterData * Band2; Extended SaveY; Band1 = dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData1")); Band2 = dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData2")); SaveY = frxReport1->Engine->CurY; for(j = 1; j <= 2; j++) { for(i = 1; i <= 6; i++) { frxReport1->Engine->ShowBand(Band1); frxReport1->Engine->ShowBand(Band2); if(i == 3) frxReport1->Engine->CurY += 10; } frxReport1->Engine->CurY = SaveY; frxReport1->Engine->CurX += 200; }