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

Crystal Reports 實現點擊列標題排序:C# 完整實戰指南

     編輯:關於C#

需求與原理

在 Crystal Reports 中實現互動式排序:使用者點擊報表列標題,頁面回傳並以該欄位切換升/降序重新渲染。核心做法是將列標題設為超連結,帶上欄位名參數回傳至同一頁面,後端動態修改 ReportDocument.DataDefinition.SortFields。

報表設計端設置(VS2005+ 內建 Crystal Reports)

  1. 右鍵列標題 → 格式化物件 → 超連結 頁籤。
  2. 選擇 網站上的檔案,輸入:ReportPage.aspx?FieldName=欄位名(如 FieldName=Location)。
  3. 右鍵報表空白處 → 記錄排序專家,將該欄位加入排序欄位(**僅加入此一欄位**,多欄位會干擾動態切換)。
格式化物件超連結設置 記錄排序專家

後端核心代碼


public partial class ReportPage : System.Web.UI.Page
{
    private static ReportDocument _reportDoc = new ReportDocument();
    private static bool _isAscending = true;      // 排序方向切換旗標
    private static bool _isPagingPostBack = false; // 分頁回傳標記

    protected void Page_Load(object sender, EventArgs e) { }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (IsPostBack)
        {
            // 1. 從 Session 還原報表文檔(避免重新查詢資料庫)
            _reportDoc = Session["Report"] as ReportDocument;
            if (_reportDoc == null) BindReport();

            crystalReportViewer.ReportSource = _reportDoc;
            _isPagingPostBack = true;
        }

        if (_isPagingPostBack)
        {
            _isPagingPostBack = false;
            return;
        }

        // 2. 處理排序參數回傳
        string fieldName = Request.QueryString["FieldName"];
        if (!string.IsNullOrEmpty(fieldName) && _reportDoc != null)
        {
            ApplySort(fieldName);
        }
    }

    private void ApplySort(string fieldName)
    {
        try
        {
            // 取得欄位定義
            FieldDefinition fieldDef = _reportDoc.Database.Tables[0].Fields[fieldName];
            _reportDoc.DataDefinition.SortFields[0].Field = fieldDef;

            // 切換排序方向
            _reportDoc.DataDefinition.SortFields[0].SortDirection = 
                _isAscending ? SortDirection.AscendingOrder : SortDirection.DescendingOrder;
            _isAscending = !_isAscending;

            // 重新綁定並重置頁碼
            crystalReportViewer.ReportSource = _reportDoc;
            crystalReportViewer.ShowFirstPage();
        }
        catch (Exception ex)
        {
            Response.Write($"排序錯誤: {ex.Message}");
        }
    }

    private void BindReport()
    {
        string sql = @"SELECT ct.XK_TEXT as Location, pt.XK_RECEIPT_DATE_TIME as DateStart, 
            pt.XK_PLU as Dept, pt.XK_RECEIPT_NUM as ReceiptNo, p.XK_TEXT as ItemNo,
            pt.XK_QUANTITY as Qty, pt.XK_AMOUNT as Amount
            FROM XK_CASH_TERMINAL ct
            LEFT JOIN XK_POS_TRANSACTION pt ON ct.XK_ID = pt.XK_CASH_TERMINAL_ID
            LEFT JOIN XK_PRODUCT p ON pt.XK_PROD_CODE = p.XK_CODE
            WHERE pt.XK_STATUS IS NULL";

        using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
        using (var adapter = new SqlDataAdapter(sql, conn))
        {
            var ds = new DataSet();
            adapter.Fill(ds);

            _reportDoc.Load(Server.MapPath("CrystalReport.rpt"));
            _reportDoc.SetDataSource(ds.Tables[0]);
            Session["Report"] = _reportDoc;
        }
    }

    protected void btnRefresh_Click(object sender, EventArgs e)
    {
        BindReport();
        crystalReportViewer.ReportSource = _reportDoc;
    }
}

關鍵技術點總結

技術點處理方式
報表物件持久化存入 Session["Report"],避免每次回傳重查 DB
排序方向切換靜態旗標 _isAscending 記錄狀態,每次點擊翻轉
分頁與排序區分_isPagingPostBack 標記區分 CrystalReportViewer 內部分頁回傳
動態修改排序操作 DataDefinition.SortFields[0],僅修改 Field 與 SortDirection

注意事項

  • 報表設計時「記錄排序專家」務必**只加入一個欄位**作為動態排序基準。
  • 生產環境需考慮 Session 狀態服務器模式(Web Farm 下 Session 需共享)。
  • 大數據量報表建議啟用資料庫端排序(修改 SQL `ORDER BY`),而非客戶端排序。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved