有机会在博客园的博问频道上看到一个问题
《ASP
NET怎么操作DataTable》
如上图左边的这个表是程序构建出来的不是数据库表怎么通过操作DataTable手段得到右边的四个表?
InsusNET尝试做了一下算是练习DataTable的功力了效果如下
根据最初数据InsusNET在aspx内放置了一个Gridview用来显示最开始的数据
复制代码 代码如下:
View Code
<asp:GridView ID=GridView runat=server AutoGenerateColumns=false>
<Columns>
<asp:TemplateField>
<HeaderTemplate>
Name
</HeaderTemplate>
<ItemTemplate>
<%# Eval(Name) %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
Quantity
</HeaderTemplate>
<ItemTemplate>
<%# Eval(Quantity) %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
创建一个DataTable并填充数据
复制代码 代码如下:
View Code
DataTable GetData()
{
DataTable table = new DataTable();
tableColumnsAdd(Name typeof(string));
tableColumnsAdd(Quantity typeof(int));
tableRowsAdd(a );
tableRowsAdd(a );
tableRowsAdd(b );
tableRowsAdd(b );
tableRowsAdd(c );
tableRowsAdd(c );
tableRowsAdd(c );
tableRowsAdd(c );
return table;
}
然后为刚才创建的Gridview绑定这个DataTable:
复制代码 代码如下:
View Code
protected void Page_Load(object sender EventArgs e)
{
if (!IsPostBack)
{
Data_Binding();
}
}
private void Data_Binding()
{
thisGridViewDataSource = GetData();
thisGridViewDataBind();
}
为了得到报表它有三个字段名称(Name)数量(Amount)和行数(Rowcount)InsusNET还参考源数据它还有一个数量(Quantity)字段因此InsusNET写了一个类别Item为以下导出报表作准备
复制代码 代码如下:
Item
using System;
using SystemCollectionsGeneric;
using SystemLinq;
using SystemWeb;
/// <summary>
/// Summary description for Item
/// </summary>
namespace InsusNET
{
public class Item
{
private string _Name;
private int _Quantity;
private int _Amount;
private int _RowCount;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public int Quantity
{
get { return _Quantity; }
set { _Quantity = value; }
}
public int Amount
{
get { return _Amount; }
set { _Amount = value; }
}
public int RowCount
{
get { return _RowCount; }
set { _RowCount = value; }
}
public Item()
{
//
// TODO: Add constructor logic here
//
}
public Item(string name int quantity)
{
this_Name = name;
this_Quantity = quantity;
}
public Item(string name int amountint rowCount)
{
this_Name = name;
this_Amount = amount;
this_RowCount = rowCount;
}
}
}
OK现在我们写一个报表在aspx放在一个按钮以及一个GridView来显示报表注意一个字段的绑定
复制代码 代码如下:
View Code
<asp:Button ID=ButtonReport runat=server Text=报表 OnClick=ButtonReport_Click />
<asp:GridView ID=GridView runat=server AutoGenerateColumns=false>
<Columns>
<asp:TemplateField>
<HeaderTemplate>
Name
</HeaderTemplate>
<ItemTemplate>
<%# Eval(Name) %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
Amount
</HeaderTemplate>
<ItemTemplate>
<%# Eval(Amount) %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
RowCount
</HeaderTemplate>
<ItemTemplate>
<%# Eval(RowCount) %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
在cs 写click事件
复制代码 代码如下:
View Code
protected void ButtonReport_Click(object sender EventArgs e)
{
SortedList<string Item> _sl = new SortedList<string Item>();
DataTable otable = GetData();
foreach (DataRow dr in otableRows)
{
if (_slContainsKey(dr[Name]ToString()))
{
_sl[dr[Name]ToString()]Amount += ConvertToInt(dr[Quantity]);
_sl[dr[Name]ToString()]RowCount += ;
}
else
{
Item i = new Item(dr[Name]ToString() ConvertToInt(dr[Quantity]) );
_slAdd(dr[Name]ToString() i);
}
}
thisGridViewDataSource = _slValues;
thisGridViewDataBind();
}
第一份报表大功告成只要DataTable数源数据有变化报表也会随之变化
接下来完成第二个报表在InsusNET使用Repeater包含Repeater来实现因此前台Html代码如下其中第一个Repeate内放置了一个HiddenField来存储名称(Name)字段当作子Repeater的参考传入
复制代码 代码如下:
View Code
<asp:Button ID=ButtonReport runat=server Text=报表 OnClick=ButtonReport_Click />
<asp:Repeater ID=Repeater runat=server OnItemDataBound=Repeater_ItemDataBound>
<ItemTemplate>
<asp:HiddenField ID=HiddenField runat=server Value=<%# ContainerDataItem %> />
<asp:Repeater ID=Repeater runat=server>
<HeaderTemplate>
<table border= cellspacing= cellpadding= style=margin: px; bordercollapse: collapse;>
<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>
首先我们需要从DataTable获取名称(Name)唯一的记录存储起来作为第一个Repeate控件的数据集数据源
复制代码 代码如下:
View Code
protected void ButtonReport_Click(object sender EventArgs e)
{
thisRepeaterDataSource = Names();
thisRepeaterDataBind();
}
List<string> Names()
{
List<string> t = new List<string>();
DataTable otable = GetData();
foreach (DataRow dr in otableRows)
{
if (!tContains(dr[Name]ToString()))
tAdd(dr[Name]ToString());
}
return t;
}
我们还要写第二个Repeater控件的数据源
复制代码 代码如下:
View Code
List<Item> GetDataByName(string name)
{
List<Item> o = new List<Item>();
DataTable otable = GetData();
foreach (DataRow dr in otableRows)
{
if (name == dr[Name]ToString())
{
Item i = new Item(dr[Name]ToString() ConvertToInt(dr[Quantity]));
oAdd(i);
}
}
return o;
}
为第二个Repeater控件绑定数据源在绑写之前得先找到这个控件因此你需要在第一个Repeater控件写OnItemDataBound=Repeater_ItemDataBound事件
复制代码 代码如下:
View Code
protected void Repeater_ItemDataBound(object sender RepeaterItemEventArgs e)
{
if (eItemItemType == ListItemTypeItem || eItemItemType == ListItemTypeAlternatingItem)
{
if (eItemFindControl(HiddenField) != null && eItemFindControl(Repeater) != null)
{
var hiddenField = eItemFindControl(HiddenField) as HiddenField;
var repeater = eItemFindControl(Repeater) as Repeater;
repeaterDataSource = GetDataByName(hiddenFieldValue);
repeaterDataBind();
}
}
}