1、加載並存儲報表
默認情況下,報表窗體同項目窗體構存儲在同一個DFM文件中。多數情況下,無須再操作,因而你就不必采用特殊方法加載報表。
如果你決定在文件中存儲報表窗體或者是數據庫的 Blob字段(他提供了非常大的彈性,你能夠在非編譯程序中修改),你必須使用“TfrxReport”提供的加載和存儲方法。
function LoadFromFile(const FileName: String; ExceptionIfNotFound: Boolean = False): Boolean;
從一個給定名字文件中加載報表。如果第二個參數等於“True”並且文件沒找到,那么他會觸發一個異常。如果文件加載成功,他返回“True”。
procedure LoadFromStream(Stream: TStream);
從流中加載報表。
procedure SaveToFile(const FileName: String);
用特殊名稱文件存儲報表。
procedure SaveToStream(Stream: TStream);
把報表存在流中。
例如:
Pascal:
frxReport1.LoadFromFile('c:\1.fr3');
frxReport1.SaveToFile('c:\2.fr3');
C++:
frxReport1->LoadFromFile("c:\\1.fr3");
frxReport1->SaveToFile("c:\\2.fr3");
2.設計報表
通過“TfrxReport.DesignReport”方法調用報表設計器。你必須在你的項目中包含報表設計器(必要條件是:要么使用“TfrxDesigner”組件,要么增加“frxDesgn”單元到uses列表)
“DesigReport” 方法接受兩個默認參數:
procedure DesignReport(Modal: Boolean = True; MDIChild: Boolean = False);
Modal參數決定設計器是否被模態,MDIChild參數允許把設計器窗體作為一個MDI子窗體。
例如:
frxReport1.DesignReport;
3.運行報表
應用下面兩個“TfrxReport”方法中的一個啟動報表:
procedure ShowReport(ClearLastReport: Boolean = True);
啟動報表並在預覽窗體中顯示。如果“ClearLastReport”參數等於“False”,報表將會增加先前的一個報表結果,否則清除前一個報表結構。
function PrepareReport(ClearLastReport: Boolean = True): Boolean;
啟動報表,沒有打開預覽窗體,參數賦值與“ShowReport”方法同名。如果報表構造成功,他返回“True”。
多數情況下,使用第一種方法更為方便一些。在報表被構造的同時,他會立刻顯示一個預覽窗體。
當需要增加另一個報表到前一個報表中的時候,“ClearLastReport”參數顯得方便些。(此類技術用於批量報表打印)。
例如:
frxReport1.ShowReport;
4.預覽報表
使用兩種途徑顯示一個報表是可能的:兩者都是調用“TfrxReport.ShowReport”方法(先前描述過了),或者使用“TfrxReport.ShowPreparedReport”方法來幫助實現。
在第二種情況下,報表構造沒有被執行,但顯示了一個完成的報表。也就是說,你要么在“PreparedReport”方法幫助下構造他,要么在構造前從文件中加載報表(查看“加載/存儲完成的報表”)
例如:
Pascal:
if frxReport1.PrepareReport then
frxReport1.ShowPreparedReport;
C++:
if(frxReport1->PrepareReport(true))
frxReport1->ShowPreparedReport();
在這種情況下,報表構造器先被完成了,並顯示在預覽窗體中。
構造一個龐大的報表可能要花費很多時間,那就是為什么使用“ShowReport”非等時同步方法會好於 “PrepareReport/ShowPreparedReport”方法。
你可以通過“TfrxReport.PreviewOptions”屬的缺省值設定預覽參數值。(這句翻譯的不夠好,請參考原文)
5、打印報表
大多數情況下,你可以從預覽窗體打印報表。要人工打印報表,你應該使用“TfrxReport.Print”方法,例如:
frxReport1.LoadFromFile(...);
frxReport1.PrepareReport;
frxReport1.Print;
同時,你可以在顯示的打印對話框中設置打印參數,你也可以使用默認設定值。
取消打印對話框,請參考“TfrxReport.PrintOptions”屬性幫助
6.載入並存儲報表
這個功能可以在預覽窗口中執行。也可以使用手工方法執行,幫助參考“TfrxReport.PreviewPages”方法:
function LoadFromFile(const FileName: String; ExceptionIfNotFound: Boolean = False): Boolean;
procedure SaveToFile(const FileName: String);
procedure LoadFromStream(Stream: TStream);
procedure SaveToStream(Stream: TStream);
賦值和參數化類似與TfrxReport相應的方法。文件包含了完成的報表,默認情況下以“FP3”為擴展名。
例如:
Pascal:
frxReport1.PreviewPages.LoadFromFile('c:\1.fp3');
frxReport1.ShowPreparedReport;
C++:
frxReport1->PreviewPages->LoadFromFile("c:\\1.fp3");
frxReport1->ShowPreparedReport();
注意,完成的報表加載完畢后,預覽方法是通過“ShowPreparedReport” 方法執行的。
7.導出報表
他可以從預覽窗口中執行。也可以手動操作,通過“FfrxReport.Export”方法,及這個方法中的參數,你可以導出你想要導出的文件類型:
frxReport1.Export(frxHTMLExport1);
導出過濾組件必須是有效的(你必須把他們放到你項目中的窗體上)並調整正確。
8.創建自定義預覽窗體
FastReport在標准的預覽窗口中顯示報表。如果因為某些原因而不適合你,你可以創建一個自定義預覽窗體。
為了這個目的,需要設計FastReport組件面板中的“TfrxReport”組 件。要顯示報表,TfrxReport.Preview方法應該連接到這個組件。
在使用TfrxPreview組件的時候,有兩個典型的問題。他不會處理按鍵(箭頭,PgUp,PgDown等等)和鼠標滾輪(如果有的話)。
要讓TfrxPreview同按鍵工作,設置焦點給他(他是可以做到的,例如,在窗體的OnShow事件句柄中)
frxPreview.SetFocus;
要讓TfrxPreview同鼠標滾輪工作,你必須創建OnMouseWheel事件句柄,並且調用TfrxPreview.MouseWheelScroll方法。
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
frxPreview1.MouseWheelScroll(WheelDelta);
end;
9.建立復合報表(批量打印)
在某些情況下,需要立刻組織幾個報表打印,或者在一個打印預覽窗體中封裝並呈現幾個報表。
要執行這些,在FastReport中有些工具能夠允許建立一個新的報表附加在一個已經存在的報表上。
“TfrxReport.PrepareReport”方法中有一個選項“ClearLasReport”布爾類型參數,默認情況下他等於True,這個參數定義了是否有必要在建立報表時清除
前一個報表。下面的方法展示了如何從兩個報表中建立一個批量報表:
Pascal:
frxReport1.LoadFromFile('1.fr3');
frxReport1.PrepareReport;
frxReport1.LoadFromFile('2.fr3');
frxReport1.PrepareReport(False);
frxReport1.ShowPreparedReport;
C++:
frxReport1->LoadFromFile("1.fr3");
frxReport1->PrepareReport(true);
frxReport1->LoadFromFile("2.fr3");
frxReport1->PrepareReport(false);
frxReport1->ShowPreparedReport();
我們加載並建立第一個報表,但並沒有顯示他。然后我們加載第二個報表到同一個TfrxReport對象,並使用“ClearLastReport”參數,讓他等於False。這就允許第二個報表
附加在先前建立的報表之后。接下來,我們在預覽窗口中顯示一個完成的報表。
9.1 復合報表中的頁數
你可以使用“Page”,“Page#”,“TotalPages”和“TotalPages#”系統變量顯示頁數或總頁數,在復合報表中,這些變量以下面的方式工作:
- Page - 當前報表頁數
- Page# - 批量報表頁數
- TotalPages - 當前報表總頁數(報表必須兩遍)
- Totalpages# - 批量報表總頁數
9.2 合並符合報表頁數
正如上面所說的,報表設計頁中的“PrintOnPrevousPage”方法讓你在打印報表的時候使用前一頁的剩余空間接合報表。在復合報表中,允許你在前一個報表的最后一頁的剩
余空間創建一個新的報表。要執行這個,要使能每一個連續報表的第一個設計頁“PrintOnPreviousePage”屬性[SPAN]
10.交互報表
在交互報表中,你可以在預覽窗口定義任意報表對象的鼠標單擊反應。例如,一個用戶能夠單擊數據線,結果運行一個帶有選擇線的明細數據。
任何報表都能交互。要執行他,你僅僅需要創建TfrxReport.OnClickObject事件句柄。下面代碼是這個事件句柄的示例:
Pascal:
procedure TForm1.frxReport1ClickObject(Page: TfrxPage; View: TfrxView; Button: TMouseButton; Shift: TShiftState; var Modified: Boolean);
begin
if View.Name = 'Memo1' then
ShowMessage('Memo1 contents:' + #13#10 + TfrxMemoView(View).Text);
if View.Name = 'Memo2' then
begin
TfrxMemoView(View).Text := InputBox('Edit', 'Edit Memo2 text:', TfrxMemoView(View).Text);
Modified := True;
end;
end;
C++:
void __fastcall TForm1::frxReport1ClickObject(TfrxView *Sender, TMouseButton Button, TShiftState Shift, bool &Modified)
{
TfrxMemoView * Memo;
if(Memo = dynamic_cast <TfrxMemoView *> (Sender))
{
if(Memo->Name == "Memo1")
ShowMessage("Memo1 contents:\n\r" + Memo->Text);
if(Memo->Name == "Memo2")
{
Memo->Text = InputBox("Edit", "Edit Memo2 text:", Memo->Text);
Modified = true;
}
}
}
11.從代碼中存取報表對象
報表對象(例如:report page, band, memo-object)是不能在你的代碼中直接存取的。這就意味着你不能通過名字尋址對象。例如,當你在你的窗體上尋址一個按鈕。
要尋址一 個對象,在TfrxReport.FindObject方法中找到幫助:
Pascal:
var
Memo1: TfrxMemoView;
Memo1 := frxReport1.FindObject('Memo1') as TfrxMemoView;
C++:
TfrxMemoView * Memo =
dynamic_cast <TfrxMemoView *> (frxReport1->FindObject("Memo1"));
然后,你就能夠尋址對象的屬性和方法。你也使用“TfrxReport.Pages”屬性尋址報表頁。
Pascal:
var
Page1: TfrxReportPage;
Page1 := frxReport1.Pages[1] as TfrxReportPage;
C++:
TfrxReportPage * Page1 = dynamic_cast <TfrxReportPage *> (frxReport1->Pages[1]);
12.從代碼中創建報表
作為一項規則,你將在設計器中創建多數報表。然而,在某些情況下(例如,當報表窗體未知的時候),使用代碼手工創建一個報表是是十分必要的。
想要手工創建一個報表,你需要執行下面的順序步驟:
-
- - 清除報表組件
- - 添加數據源
- - 添加數據頁
- - 添加報表頁
- - 添加欄頁
- - 設置欄屬性,接着把他們同數據相連
- - 在每個欄上加入對象
- - 設置對象屬性,接着把他們同數據相連
讓我們來檢查一下創建一個簡單報表的類型列表。
假設我們擁有如下組件:
frxReport1: TfrxReport and frxDBDataSet1: TfrxDBDataSet(最后一個連接到DBDEMOS數據,Customer.db表)。
我們的報表將包含一個帶有報表標題和主數據欄的頁。在報表標題欄上有一個帶有“Hellow FastReport”文本的對象,主數據欄包含一個帶有連接到“CustNo”字段的對象。
Pascal:
var
DataPage: TfrxDataPage;
Page: TfrxReportPage;
Band: TfrxBand;
DataBand: TfrxMasterData;
Memo: TfrxMemoView;
{ 清除報表 }
frxReport1.Clear;
{ 為報表添加數據集到可存取的列表中 }
frxReport1.DataSets.Add(frxDBDataSet1);
{ 添加"Data"頁 }
DataPage := TfrxDataPage.Create(frxReport1);
{ 添加頁 }
Page := TfrxReportPage.Create(frxReport1);
{ 創建唯一名稱 }
Page.CreateUniqueName;
{ 設置默認字段大小, 紙張和打印方向 }
Page.SetDefaults;
{ 修改紙張方向 }
Page.Orientation := poLandscape;
{ 添加一個報表標題欄 }
Band := TfrxReportTitle.Create(Page);
Band.CreateUniqueName;
{ it is sufficient to set the ?Top? coordinate and height for a band }
{ both coordinates are in pixels }
Band.Top := 0;
Band.Height := 20;
{ 為標題欄添加一個對象 }
Memo := TfrxMemoView.Create(Band);
Memo.CreateUniqueName;
Memo.Text := 'Hello FastReport!';
Memo.Height := 20;
{ 這個對象將伸展坐標到欄的寬度 }
Memo.Align := baWidth;
{ 添加主數據欄 }
DataBand := TfrxMasterData.Create(Page);
DataBand.CreateUniqueName;
DataBand.DataSet := frxDBDataSet1;
{ 頂端的調整應當比先前加入欄的頂部+高度大一些 }
DataBand.Top := 100;
DataBand.Height := 20;
{ 在主數據欄上添加一個對象 }
Memo := TfrxMemoView.Create(DataBand);
Memo.CreateUniqueName;
{ 連接數據 }
Memo.DataSet := frxDBDataSet1;
Memo.DataField := 'CustNo';
Memo.SetBounds(0, 0, 100, 20);
{ 調整文本到右側的對象邊緣 }
Memo.HAlign := haRight;
{ 顯示報表 }
frxReport1.ShowReport;
C++:
TfrxDataPage * DataPage;
TfrxReportPage * Page;
TfrxBand * Band;
TfrxMasterData * DataBand;
TfrxMemoView * Memo;
// 清除報表
frxReport1->Clear();
// 在報表上添加一個數據集到數據集存取列表
frxReport1->DataSets->Add(frxDBDataset1);
// 添加“數據”頁
DataPage = new TfrxDataPage(frxReport1);
// 添加一頁
Page = new TfrxReportPage(frxReport1);
// 創建一個不重復的名稱
Page->CreateUniqueName();
// 設置域大小, 紙張和默認的打印方向
Page->SetDefaults();
// 修改紙張的打印方向
Page->Orientation = poLandscape;
// 增加一個報表標題欄
Band = new TfrxReportTitle(Page);
Band->CreateUniqueName();
// 為欄充分設置頂部坐標和高度
// 在像素上包含坐標
Band->Top = 0;
Band->Height = 20;
// 在報表標題欄加入一個對象
Memo = new TfrxMemoView(Band);
Memo->CreateUniqueName();
Memo->Text = "Hello FastReport!";
Memo->Height = 20;
// 此對象將會被按照欄的寬度延展
Memo->Align = baWidth;
// 添加主數據欄
DataBand = new TfrxMasterData(Page);
DataBand->CreateUniqueName();
DataBand->DataSet = frxDBDataset1;
// 頂部坐標應該大於前邊添加欄的頂部坐標+高度
DataBand->Top = 100;
DataBand->Height = 20;
// 主數據上加入一個對象
Memo = new TfrxMemoView(DataBand);
Memo->CreateUniqueName();
// 連接到數據
Memo->DataSet = frxDBDataset1;
Memo->DataField = "CustNo";
Memo->SetBounds(0, 0, 100, 20);
// 調整文本到右側對象的空白
Memo->HAlign = haRight;
// 顯示報表
frxReport1->ShowReport(true);
讓我們來解釋一些細節:
所有在報表中使用的數據集都必須添加到數據源列表中,在我們示例中,是用frxReport1.DataSets.Add(frxDBDataSet1)這一行執行的。否則,報表就不會工作。
數據頁對於插入內部數據集是必要的,例如TfrxADOTable。這些數據集只能放在數據頁。
調用Page.SetDefaults不是必須的,因為在這個案例中頁A4紙張設置和頁邊距都是0毫米。默認值設置10毫米頁邊距,並捕獲打印機頁大小和對齊方式。
在增加欄到頁面的同時,你要確認他們沒有互相重疊在一起。要執行他,頂部和高度的坐標是相似的。總是要在設計器中定位相同的位置的。
對象的坐標和大小是以像素為單位的,因為所有對象的left, Top, Width和Height屬性都擁有擴展類型,你能夠指出非整形值。下面常量用於轉化像素到厘米和英寸:
fr01cm = 3.77953;
fr1cm = 37.7953;
fr01in = 9.6;
fr1in = 96;
例如,一個欄的高度等於5毫米如下設定:
Band.Height := fr01cm * 5;
Band.Height := fr1cm * 0.5;
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Delphi FastReport報表常用方法
1. 單據中有多行數據,但預覽時只顯示部分內容,或者打印內容行與行之間有間隔
FASTREPOR屬性中:設置RowCount=0,Start New Page為False;Stretched為True.
說明:
RowCount:控制總共打印幾行;RowCount=0是打印全部;
Start New Page:打印前先跳頁;每頁打印一行;
Stretch:表身自動伸縮根據表身內容;
2. 在打印中設置金額或數量的小數位數
FASTREPOR屬性中:使用DisplayFormat(數據顯示格式)——數字——1234.50
- %2.0f:以整數形式顯示;
- %2.2f:顯示兩位小數;
- %2.3f:顯示三位小數位,可根據情況進行調整。
3. 在打印中設置日期/時間的格式
FASTREPOR屬性中:使用DisplayFormat(數據顯示格式)——日期/時間——11.28.2002
mm.dd.yyyy:顯示月.日.年
mm.dd:顯示月.日
mm:顯示兩位的月
4. 當欄位的值為零時顯示為空
FASTREPOR屬性中:設置HideZeros(數字前面的0是否顯示)為True
5. 自動換行
1)選擇數據單元進行群組;
2)StretchMode為smMaxHtight;WordWrap為True;Stretched為True.
說明:
StretchMode:對象伸縮的行為;
WordWrap:文本是否自動換行;
6. 合計
[SUM(<進/銷/退/折表身檔."AMTN_NET">,MasterData2)]
7. 每頁合計
將定義好的合計函數放到‘欄尾’中即可。
8. 全表合計
將定義好的合計函數放到‘報表合計’中即可。
9. 金額大寫
在報表設計中使用函數:ConbertNumToChinese()
合計金額大寫:[ConvertNumToChinese(SUM(<進/銷/退/折表身檔."AMTN_NET">,MasterData2))]
負數合計金額大寫:[ConvertNumToChinese(Abs(SUM(<進/銷/退/折表身檔."AMTN_NET">,MasterData2)))]
10. 報表中打印行數
在報表設計中使用變量——系統變量Line#
11. 連打
1) 單據——速查,查出要打印的單據;
2)打印——查詢數據——預覽——打印,選擇多張單據進行連打。
12. 連打打到同一頁
打印——設計——頁面設置——勾選“打印至前一頁”,“伸展至打印區”
13. 打印固定行數,不足補空白行代碼(語言:PascalScript)
var PageLine: integer; PageMaxRow: integer=5; //每頁打印的行數 procedure Footer1OnBeforePrint(Sender: TfrxComponent); var i: integer; begin i := iif(PageLine=0, PageMaxRow, PageLine); while i < PageMaxRow do begin i := i + 1; Engine.ShowBand(Child1); //印空白表格 end; end; procedure MasterData2OnBeforePrint(Sender: TfrxComponent); begin PageLine := <line> mod PageMaxRow; if (PageLine = 1) and (<line> > 1) then Engine.newpage; end; end.
14. 電子簽名代碼(語言:BasicScript)
sub MasterData2OnBeforePrint(Sender)
if length(<進銷貨表頭檔.”CHK_MAN”>)>0 then picture2.visible=true
end sub
---------------------------------------------------------