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

ASP.NET DataTable 進階操作實戰:從原始資料產生多維報表與巢狀 Repeater 綁定技巧

     編輯:ASP.NET 基礎

情境描述

給定一個記憶體內建立的 DataTable(非資料庫來源),包含 Name、Quantity 兩欄,需產出四種不同維度的報表:

  1. 彙總報表:每一 Name 的總量與筆數。
  2. 明細分組報表:依 Name 分組,每組顯示所有明細列。
  3. 交叉分析報表(略)。
  4. 動態樞紐報表(略)。

資料準備與基礎繫結


// 建立來源 DataTable
DataTable GetData()
{
    var dt = new DataTable();
    dt.Columns.Add("Name", typeof(string));
    dt.Columns.Add("Quantity", typeof(int));
    dt.Rows.Add("a", 1); dt.Rows.Add("a", 2);
    dt.Rows.Add("b", 2); dt.Rows.Add("b", 2);
    dt.Rows.Add("c", 1); dt.Rows.Add("c", 2);
    dt.Rows.Add("c", 3); dt.Rows.Add("c", 4);
    return dt;
}

// 頁面載入繫結原始資料到 GridView1
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack) GridView1.DataSource = GetData(); GridView1.DataBind();
}

報表一:彙總統計(SortedList + 自訂實體類別)

定義 Item 類別承載彙總欄位:


public class Item
{
    public string Name { get; set; }
    public int Quantity { get; set; }   // 最後一筆或單筆用
    public int Amount { get; set; }     // 總和
    public int RowCount { get; set; }   // 筆數
}

按鈕事件中以 SortedList<string, Item> 彙總:


protected void ButtonReport1_Click(object sender, EventArgs e)
{
    var sl = new SortedList<string, Item>();
    foreach (DataRow dr in GetData().Rows)
    {
        string key = dr["Name"].ToString();
        int qty = Convert.ToInt32(dr["Quantity"]);
        if (sl.ContainsKey(key))
        {
            sl[key].Amount += qty;
            sl[key].RowCount++;
        }
        else
        {
            sl.Add(key, new Item { Name = key, Amount = qty, RowCount = 1 });
        }
    }
    GridView2.DataSource = sl.Values;
    GridView2.DataBind();
}

報表二:巢狀 Repeater 實現分組明細

外層 Repeater 綁定唯一 Name 清單,內層 Repeater 依 Name 篩選明細。

前端標記


<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
  <ItemTemplate>
    <asp:HiddenField ID="HiddenField1" Value='<%# Container.DataItem %>' />
    <asp:Repeater ID="Repeater2" runat="server">
      <HeaderTemplate><table><tr><td>Name</td><td>Quantity</td></tr></HeaderTemplate>
      <ItemTemplate><tr><td><%# Eval("Name") %></td><td><%# Eval("Quantity") %></td></tr></ItemTemplate>
      <FooterTemplate></table></FooterTemplate>
    </asp:Repeater>
  </ItemTemplate>
</asp:Repeater>

後端邏輯


// 取得不重複 Name 清單
List<string> GetNames()
{
    var list = new List<string>();
    foreach (DataRow dr in GetData().Rows)
        if (!list.Contains(dr["Name"].ToString())) list.Add(dr["Name"].ToString());
    return list;
}

// 依 Name 取得明細
List<Item> GetDetails(string name)
{
    var list = new List<Item>();
    foreach (DataRow dr in GetData().Rows)
        if (dr["Name"].ToString() == name)
            list.Add(new Item { Name = name, Quantity = Convert.ToInt32(dr["Quantity"]) });
    return list;
}

protected void ButtonReport2_Click(object sender, EventArgs e)
{
    Repeater1.DataSource = GetNames();
    Repeater1.DataBind();
}

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        var hf = e.Item.FindControl("HiddenField1") as HiddenField;
        var rpt = e.Item.FindControl("Repeater2") as Repeater;
        if (hf != null && rpt != null)
        {
            rpt.DataSource = GetDetails(hf.Value);
            rpt.DataBind();
        }
    }
}

進階技巧與效能優化

技巧說明
LINQ to DataTablevar groups = dt.AsEnumerable().GroupBy(r => r.Field<string>("Name")); 可大幅簡化分組邏輯。
DataView.RowFilter內層 Repeater 可用 new DataView(dt) { RowFilter = "Name='a'" } 避免重複迴圈。
快取 DataTable若來源資料不常變,放入 Cache["SourceData"] 減少重建開銷。
虛擬化分頁資料量大時,搭配 DataPager 或自訂分頁邏輯,避免一次綁定過多列。

總結

透過 SortedList 快速彙總、巢狀 Repeater + HiddenField 傳遞分組鍵值、ItemDataBound 動態綁定子資料源,即可在純記憶體 DataTable 上靈活產出多維報表。實務上建議配合 LINQ 與快取機制,進一步提升開發效率與執行效能。

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