首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 服務器組件解決 Web 交叉報表(二):FastReport 導出到記憶體流修改詳解

     編輯:Delphi

承接上篇,Web 環境下為避免磁盤權限與安全問題,需將 FastReport 2.5 生成的報表直接導出到記憶體流(TMemoryStream)。本文詳細說明修改 FR_Class 與 TfrHTML2Export 源碼以支援 ExportToStream 並內嵌 CSS 的完整步驟。

1. 為 TfrReport 添加 ExportToStream 方法

在 FR_Class.pas 的 TfrReport 類別中加入:

// 添加導出到記憶體流支援 -- Conch 2007-09-10
procedure TfrReport.ExportToStream(Filter: TfrExportFilter; Stream: TMemoryStream);
var
  S: String;
  Flag, NeedConnect: Boolean;
begin
  DocMode := dmPrinting;
  FCurrentFilter := Filter;
  if (Preview <> nil) and (EMFPages.Count = 0) then
  begin
    Preview.Disconnect;
    NeedConnect := True;
  end
  else
    NeedConnect := False;

  Flag := True;
  if Assigned(FCurrentFilter.OnBeforeExport) then
    FCurrentFilter.OnBeforeExport(FCurrentFilter.FileName, Flag);
  FCurrentFilter.Stream := Stream;  { 關鍵:指定輸出流 }

  CurReport := Self;
  MasterReport := Self;
  SavedAllPages := EMFPages.Count;

  FCurrentFilter.OnBeginDoc;
  ExportBeforeModal(Self);

  if Assigned(FCurrentFilter.OnAfterExport) then
    FCurrentFilter.OnAfterExport(FCurrentFilter.FileName);

  if NeedConnect then
    Preview.Connect(Self);
  FCurrentFilter := nil;
end;

2. 修改 TfrHTML2Export.OnEndDoc 內嵌 CSS

原版將 CSS 另存為 .css 檔案,導致記憶體流中的 HTML 缺少樣式。找到 SaveStringToFile(ImageFolderFull + CSSFile, S)(FR 2.5 約第 461 行),改為:

if FileName <> '' then
  SaveStringToFile(ImageFolderFull + CSSFile, S)
else begin
  S := '' + LF;
  Stream.Write(S[1], Length(S));  { 直接寫入記憶體流 }
end;

3. 完整修改後的 OnEndDoc(關鍵片段)

procedure TfrHTML2Export.OnEndDoc;
var
  S: string; I, J: Integer; Page: THPage; LastBottom: Integer;
  CSSFile, CSSFilePrint, NavFile: string;
  H1, H2: string; MaxWidth, MinLeftMargin: Integer;
begin
  if Navigator = nil then Exit;
  if FPages.Count = 0 then Exit;

  { ... 樣式構建代碼省略 ... }

  { 關鍵修改:CSS 內嵌到流 }
  if FileName <> '' then
    SaveStringToFile(ImageFolderFull + CSSFile, S)
  else begin
    S := '' + LF;
    Stream.Write(S[1], Length(S));
  end;

  { ... 後續分頁/導航器輸出代碼 ... }
  { 注意:所有原本寫檔案的 SaveStringToFile 均需改為 Stream.Write }
end;

4. 調用方式

var
  Rpt: TfrReport;
  Ex: TfrHTML2Export;
  St: TMemoryStream;
begin
  Rpt := TfrReport.Create(nil);
  Ex := TfrHTML2Export.Create(nil);
  St := TMemoryStream.Create;
  try
    Rpt.LoadFromFile('Report.frf');
    Rpt.PrepareReport;
    Ex.Navigator.Align := haLeft;
    Ex.ShowDialog := False;
    Rpt.ExportToStream(Ex, St);  { 導出到記憶體流 }
    St.Position := 0;
    { 將 St 內容發送給 HTTP 客戶端 }
  finally
    Ex.Free; St.Free; Rpt.Free;
  end;
end;

5. 其他導出組件說明

  • TfrHTMExport:表格模式導出,預設無框線、存在數據錯位,不推薦。
  • TfrHTML2Export:CSS 絕對定位模式,完美保真,本文採用此組件。
  • Excel 導出:基於 OLE 自動化,必須寫入實體檔案,無法直接導出到流。

6. 效能與安全優勢

指標檔案導出記憶體流導出
磁盤 I/O有無
權限問題需寫入權限無
殘留檔案清理需定時清理自動隨流釋放
併發衝突檔案名衝突各請求獨立流
延遲較高極低

通過修改 FastReport 源碼新增 ExportToStream 並內嵌 CSS,即可在 Web 服務器組件中高效、安全地生成交叉報表 HTML,無需臨時檔案,完美解決權限與併發問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved