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

Delphi 服務器組件解決 Web 交叉報表(一):ActiveX + FastReport 跨庫查詢與動態報表架構

     編輯:Delphi

Web 開發中交叉報表最棘手。本文展示如何用 Delphi 建立 ActiveX 服務器組件,結合 FastReport 2.5 解決跨資料庫服務器查詢與動態交叉報表生成,並透過記憶體流直接輸出 HTML 避免檔案權限問題。

1. 業務場景與難點

  • 跨庫查詢:各分公司帳套對應不同資料庫,分佈在多台 SQL Server,需跨服務器聯表。
  • 交叉報表:行=調出分公司,列=調入客戶,值=調貨量,動態列數不可預知。
  • Web 部署:無成熟 Web 報表控件,需自建服務端組件。

2. 架構設計

ASP.NET 頁面
    ↓ Server.CreateObject("CrossReport.kktWebCrossReport")
Delphi ActiveX DLL (kktWebCrossReport.dll)
    ├─ ShowCrossReport(ConStr, Command, ReportFile)
    │   ├─ ADOQuery 跨庫查詢 (OpenQuery/OpenRowset)
    │   ├─ TfrReport 載入 .frf 模板
    │   ├─ TfrReport.PrepareReport (交叉報表自動展開)
    │   └─ TfrHTML2Export + ExportToStream → TMemoryStream
    └─ Response.Write(MemoryStream 內容)

3. 創建 ActiveX Library 專案

  1. File → New → ActiveX Library,專案名 CrossReport。
  2. File → New → Active Server Object,類別名 TkktWebCrossReport,介面 IkktWebCrossReport。
  3. 在類型庫編輯器添加方法 ShowCrossReport:
function ShowCrossReport(const ConStr, Command, ReportFile: WideString): Integer; safecall;

4. 核心實現代碼

function TkktWebCrossReport.ShowCrossReport(const ConStr, Command, ReportFile: WideString): Integer;
var
  ADOQ: TADOQuery;
  Rpt: TfrReport;
  St: TMemoryStream;
  Ex: TfrHTML2Export;
  Buf: String;
  E: TComponent;
begin
  E := TComponent.Create(nil);  { 統一擁有者,統一釋放 }
  try
    ADOQ := TADOQuery.Create(E);
    try
      ADOQ.Name := 'ADOQ';
      ADOQ.ConnectionString := ConStr;
      ADOQ.SQL.Add(Command);
      ADOQ.Open;  { 執行跨庫查詢 }

      St := TMemoryStream.Create;
      Rpt := TfrReport.Create(E);
      Rpt.Name := 'frReport1';
      Rpt.LoadFromFile(ReportFile);  { 載入 .frf 模板 }
      Rpt.ShowProgress := False;
      Rpt.PrepareReport;  { 關鍵:交叉報表展開發生在這裡 }

      Ex := TfrHTML2Export.Create(E);
      Ex.Navigator.Align := haLeft;
      Ex.ShowDialog := False;
      Rpt.ExportToStream(Ex, St);  { 導出到記憶體流,見下篇源碼修改 }

      St.Position := 0;
      SetLength(Buf, St.Size);
      St.Read(Buf[1], St.Size);
      Response.Write(Buf);  { 直接寫入 HTTP 回應 }
    except
      on Ex: Exception do
        Response.Write('

' + Ex.Message + '

'); end; finally E.Free; { 釋放所有子組件 } end; end;

5. 跨庫查詢 SQL 技巧

{ 使用 OPENQUERY 連結服務器 }
SELECT * FROM OPENQUERY([Server1], 'SELECT * FROM Db1.dbo.TransferOut')
UNION ALL
SELECT * FROM OPENQUERY([Server2], 'SELECT * FROM Db2.dbo.TransferOut')
  • 在 SQL Server 配置連結服務器,OPENQUERY 可跨實例查詢。
  • ASP.NET 傳入連接字串指向主庫,主庫再分發跨庫查詢。

6. FastReport 交叉報表模板設計

  1. 新建報表,放置 Cross Band(交叉帶)。
  2. 拖放字段:行=帳套名稱,列=客戶名稱,值=調貨量(Sum)。
  3. 保存為 rpt1.frf 部署至服務器。

報表模板設計

7. ASP.NET 調用代碼

Private Sub ShowReport()
  Dim Cmd As String = ParseSQL()  { 動態生成查詢 SQL }
  If Cmd <> "" Then
    Dim CrossReport = Server.CreateObject("CrossReport.kktWebCrossReport")
    CrossReport.ShowCrossReport(clsSQL.DefaultConStr, Cmd, Page.MapPath(".") + "rpt1.frf")
    CrossReport = Nothing
  End If
End Sub

8. 部署步驟

  1. 編譯 ActiveX Library 產生 CrossReport.dll。
  2. 複製至 Web 服務器目錄(如 C:\Inetpub\CrossReport\)。
  3. 管理員命令提示字元執行 regsvr32 CrossReport.dll 註冊。
  4. IIS 應用程式池啟用 32 位應用程式(若 Delphi 32 位編譯)。
  5. 測試 ASP.NET 頁面調用。

9. 關鍵優勢總結

痛點解決方案
跨庫查詢複雜SQL Server 連結服務器 + OPENQUERY,邏輯集中在 SQL
交叉報表動態列FastReport Cross Band 自動展開,無需手寫轉換代碼
Web 無報表控件Delphi ActiveX 封裝 FastReport,ASP.NET 透過 COM 調用
檔案權限/安全ExportToStream 導出到記憶體流,無臨時檔案
併發衝突每請求獨立 MemoryStream,無共享資源

下篇將詳細說明 FastReport 源碼修改以支援 ExportToStream 與 CSS 內嵌。

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