原本在開發(fā)一個(gè)報(bào)表插件,因?yàn)樾枰h(yuǎn)程傳輸,因此需要序列化報(bào)表,序列化FastReport有兩種方式,
1.僅序列化數(shù)據(jù),由客戶端接受到數(shù)據(jù),并呈現(xiàn)報(bào)表,這種方式需要在客戶端存儲(chǔ)報(bào)表格式文件xxx.Frf,
2.序列化FastReport的結(jié)果集(即,得到數(shù)據(jù)后可以存成的frp文件),這樣frf文件不需要在客戶端存在.我傾向于采用這種方式,畢竟客戶端越輕越好.
簡(jiǎn)單打開一個(gè)表之后,將fr生成結(jié)果存成frp后,發(fā)現(xiàn)有64k大,這是不能忍受的,這還僅僅是2xx數(shù)據(jù)而已,不過這個(gè)問題解決也很簡(jiǎn)單,壓縮之(只有4K),d7自帶的就有一個(gè)壓縮單元zLib,至于zlib的用法很簡(jiǎn)單,它提供Stream和string 的壓縮方式.這里就不說了,既然這個(gè)問題解決了,就剩序列化的代碼,
序列化的過程很簡(jiǎn)單,其實(shí)了解了fr的幾個(gè)重要方法之后,就很簡(jiǎn)單了,得到的成果如下:
在服務(wù)器端
    frReport1.Dataset := FrDbDataset1; //設(shè)置frReport的Dataset屬性
    FrDbDataset1.DataSet := Adoquery1; //鏈接frDbDataset和Dataset實(shí)例
    AdoQuery1.Open; //取得數(shù)據(jù)
    frReport1.LoadFromFile('d:/1.frf'); //載入一個(gè)報(bào)表格式文件
    frReport1.PRepareReport; //執(zhí)行報(bào)表,得到數(shù)據(jù),并不顯示
    frReport1.SavePreparedReport('d:/3.frp'); //將報(bào)表的結(jié)果存成文件
//載入3.frp,就可以得到序列化的數(shù)據(jù),但是這樣要訪問硬盤,不爽.看看SavePreparedReport的代碼
procedure TfrReport.SavePreparedReport(FName: String); 
var 
  Stream: TFileStream; 
begin 
  Stream := TFileStream.Create(FName, fmCreate); 
  EMFPages.SaveToStream(Stream); 
  Stream.Free; 
end; 
既然這樣,看看EMFPages是否是public的,看來是可以的,那么我們可以將最后改成
Stream := TMemoryStream.Create; 
  EMFPages.SaveToStream(Stream); 
result := Stream;
客戶端
更簡(jiǎn)單,你不需要任何的數(shù)據(jù)集,甚至連frReport類的實(shí)例也可以動(dòng)態(tài)生成,
with TfrReport.Create(nil) do 
    begin 
        try 
            LoadPreparedReport('d:/2.frp'); //也可以改成上面流的形式,用EMFPages
            ShowPreparedReport; 
        finally 
            Free; 
        end; 
    end; 
在這個(gè)問題的解決中,可以學(xué)到FastReport的幾個(gè)主要方法
PrepareReport//使報(bào)表從數(shù)據(jù)集得到數(shù)據(jù)
ShowPreparedReport//顯示已經(jīng)得到數(shù)據(jù)的報(bào)表,注意和ShowReport的區(qū)別,其實(shí)ShowReport的實(shí)現(xiàn)看看就明白了)
LoadPreparedReport//從frp載入一個(gè)結(jié)果
SavePreparedReport//將結(jié)果存成一個(gè)文件
LoadFromFile//載入報(bào)表格式文件
| 
 
 | 
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注