首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# WinForms RDLC 報表框架:BaseReportForm 完整設計與配置驅動開發

     編輯:關於C#

設計目標

封裝 Microsoft.Reporting.WinForms.ReportViewer,提供:

  • 統一報表標題、頁首/頁尾、頁邊距、紙張方向配置。
  • 資料綁定與參數傳遞標準化。
  • 列印、匯出(PDF/Excel/Word)一鍵完成。
  • 配置檔驅動,減少硬編碼。

核心類別結構

public abstract class BaseReportForm : Form
{
    protected ReportViewer ReportViewer { get; private set; }
    public string ReportConfigFile { get; set; } // *.rps
    public string QueryConfigFile { get; set; }  // *.pcs
    public string PrintConfigFile { get; set; }  // *.rps (列印專用)

    protected BaseReportForm()
    {
        ReportViewer = new ReportViewer { Dock = DockStyle.Fill };
        Controls.Add(ReportViewer);
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        LoadReportConfig();
        BindData();
        ReportViewer.RefreshReport();
    }

    protected virtual void LoadReportConfig()
    {
        // 解析 *.rps XML,設定 ReportViewer.LocalReport.PageSettings、頁首頁尾文字等
    }

    protected abstract void BindData(); // 子類實作資料來源綁定

    protected virtual void SetReportConfig(ReportConfig config)
    {
        // 子類覆寫動態設定頁首頁尾參數(公司名、操作員、列印日期、頁碼)
    }
}

報表配置檔 (*.rps) 完整結構

<?xml version="1.0" encoding="utf-8"?>
<ReportConfig>
  <Title>銷售明細報表</Title>
  <ColumnConfigFile>frmSalesReport</ColumnConfigFile> <!-- 對應 *.cls 欄位配置 -->
  <PaperSize>
    <Width>29.7</Width>  <!-- CM -->
    <Height>21</Height>
  </PaperSize>
  <Margins>
    <Left>1.5</Left> <Top>1</Top> <Right>1.5</Right> <Bottom>1</Bottom>
  </Margins>
  <Landscape>true</Landscape>
  <Header>
    <Height>3</Height> <!-- CM -->
    <Objects>
      <Label>
        <Key>Company</Key>
        <Text></Text> <!-- 由程式動態填入 -->
        <HAlign>Center</HAlign> <AutoCenter>true</AutoCenter>
        <Font><Name>微軟正黑體</Name><Size>16</Size></Font>
        <Location><X>0</X><Y>0.5</Y></Location>
        <Size><Width>0</Width><Height>1</Height></Size>
      </Label>
      <Label>
        <Key>Title</Key>
        <Text></Text>
        <HAlign>Center</HAlign> <AutoCenter>true</AutoCenter>
        <Font><Name>微軟正黑體</Name><Size>14</Size></Font>
        <Location><X>0</X><Y>1.5</Y></Location>
        <Size><Width>0</Width><Height>0.8</Height></Size>
      </Label>
      <Label>
        <Key>Operator</Key>
        <Text>操作員:{0}</Text>
        <HAlign>Left</HAlign> <Location><X>0.5</X><Y>2.5</Y></Location>
      </Label>
      <Label>
        <Key>PrintDate</Key>
        <Text>列印日期:{0:yyyy/MM/dd}</Text>
        <HAlign>Right</HAlign> <AutoRight>true</AutoRight>
        <Location><X>0</X><Y>2.5</Y></Location>
      </Label>
    </Objects>
  </Header>
  <Footer>
    <Height>1</Height>
    <Objects>
      <Label>
        <Key>Page</Key>
        <Text>第 {PageNumber} 頁 / 共 {TotalPages} 頁</Text>
        <HAlign>Right</HAlign> <AutoRight>true</AutoRight>
        <Location><X>0</X><Y>0.2</Y></Location>
      </Label>
    </Objects>
  </Footer>
</ReportConfig>

欄位配置檔 (*.cls) 對應報表資料集欄位

<Columns>
  <Column><Key>OrderNo</Key><Text>訂單編號</Text><Width>3</Width><Align>Center</Align></Column>
  <Column><Key>ProductName</Key><Text>商品名稱</Text><Width>6</Width><Align>Left</Align></Column>
  <Column><Key>Qty</Key><Text>數量</Text><Width>1.5</Width><Align>Right</Align><Type>NumberColumn</Type><Formater>N0</Formater></Column>
  <Column><Key>Amount</Key><Text>金額</Text><Width>2</Width><Align>Right</Align><Type>NumberColumn</Type><Formater>C2</Formater></Column>
  <Column><Key>OrderDate</Key><Text>下單日期</Text><Width>2.5</Width><Align>Center</Align><Type>DateTimeColumn</Type><Formater>yyyy/MM/dd</Formater></Column>
</Columns>

子類實作範例

public class SalesReportForm : BaseReportForm
{
    public SalesReportForm()
    {
        ReportConfigFile = "frmSalesReport.rps";
        QueryConfigFile = "frmSalesReport.pcs";
    }

    protected override void BindData()
    {
        // 1. 取得查詢條件(從 QueryConfig 對應的查詢視窗回傳)
        var qb = QueryBuilder.FromConfig(QueryConfigFile); // 假設有解析器

        // 2. 查詢資料
        var dal = new SalesDAL();
        var dt = dal.GetSalesData(qb); // 回傳 DataTable

        // 3. 設定報表資料來源
        ReportViewer.LocalReport.DataSources.Clear();
        ReportViewer.LocalReport.DataSources.Add(new ReportDataSource("SalesDataSet", dt));

        // 4. 設定報表內嵌 RDLC 路徑
        ReportViewer.LocalReport.ReportEmbeddedResource = "MyApp.Reports.SalesReport.rdlc";

        // 5. 動態設定頁首參數
        SetReportConfig(ReportConfig);
    }

    protected override void SetReportConfig(ReportConfig config)
    {
        base.SetReportConfig(config);
        config.Header.FindObject("Company")?.SetText(AppContext.CompanyName);
        config.Header.FindObject("Title")?.SetText("2024 年度銷售明細");
        config.Header.FindObject("Operator")?.SetText(string.Format("操作員:{0}", AppContext.UserName));
        config.Header.FindObject("PrintDate")?.SetText(string.Format("列印日期:{0:yyyy/MM/dd}", DateTime.Today));
    }
}

RDLC 設計要點

  • 資料集名稱需與 ReportDataSource 名稱一致(如 "SalesDataSet")。
  • 頁首/頁尾區域放置 TextBox,Value 設為 =Parameters!Company.Value 等參數。
  • 頁碼運算式:=Globals!PageNumber / =Globals!TotalPages。
  • 群組小計/總計:在 Tablix 群組屬性加入總計列,運算式 =Sum(Fields!Amount.Value)。

列印與匯出

// 直接列印(無預覽)
ReportViewer.PrintDialog(); // 或 PrintToPrinter()

// 匯出 PDF
byte[] pdf = ReportViewer.LocalReport.Render("PDF");
File.WriteAllBytes("Report.pdf", pdf);

// 匯出 Excel
byte[] excel = ReportViewer.LocalReport.Render("EXCELOPENXML"); // .xlsx
File.WriteAllBytes("Report.xlsx", excel);

總結

BaseReportForm 以 配置檔驅動 + 抽象基類 + RDLC 模板 三位一體,實現報表開發標準化:版面調整改 XML、資料邏輯寫子類、樣式調整改 RDLC。配合 *.cls 欄位配置複用,新增報表只需建立三個 XML + 一個 RDLC + 一個子類,大幅降低維護成本。

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