最近在公司碰到这样一个报表,这个报表需显示主表和细节表的资料并且统计细节表的某个栏位,而且还要分页显示,这个不是简单的单元格合并就能解决的问题,我曾试着合并单元格,但是分页不是用户想要的效果,所以我采用了一个怪异的方式解决了。效果如下图:
具体的实现我就不详细介绍了,把代码贴上来,供有相同需求的朋友参考吧。
aspx:
<asp:UpdatePanel ID="upData" runat="server">
<ContentTemplate>
<cust:CustGridView ID="gvData" runat="server" DataKeyNames="P1">
<AlternatingRowStyle CssClass="trEven" />
<RowStyle HorizontalAlign="Center" />
<Columns>
<asp:BoundField HeaderText="头一" DataField="P1" HeaderStyle-Width="5%" />
<asp:BoundField HeaderText="头二" DataField="P2" HeaderStyle-Width="30%" />
<asp:TemplateField>
<HeaderTemplate>
头三</th><th>头四</th><th>头五
</HeaderTemplate>
<ItemTemplate>
<asp:Repeater ID="rptDtl" runat="server">
<ItemTemplate>
<asp:Literal ID="ltlTr1" runat="server" />
<%#Eval("D1")%></td>
<td><%#Eval("D2")%></td>
<td><%#Eval("D3")%></td></tr>
</ItemTemplate>
<FooterTemplate>
<asp:Literal ID="ltlTotal" runat="server" />
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</cust:CustGridView>
</ContentTemplate>
</asp:UpdatePanel>
cs:
public partial class Ap_Test3 : VTBasePage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
gvData.PageSize = 10;
gvData.AllowPaging = true;
gvData.AutoGenerateColumns = false;
gvData.RowDataBound += new GridViewRowEventHandler(gvData_RowDataBound);
gvData.DataSource = Obj.GetObjList();
gvData.DataBind();
}
}
void gvData_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Pager)
{
e.Row.Cells[0].ColumnSpan = gvData.Columns.Count + 2;
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
int p1 = (int)gvData.DataKeys[e.Row.RowIndex]["P1"];
e.Row.Cells[0].RowSpan = Obj.GetDtlSize(p1);
e.Row.Cells[1].RowSpan = Obj.GetDtlSize(p1);
Repeater rptDtl = e.Row.FindControl("rptDtl") as Repeater;
if (rptDtl != null)
{
rptDtl.DataMember = e.Row.RowIndex + "," + p1.ToString();
rptDtl.ItemDataBound += new RepeaterItemEventHandler(rptDtl_ItemDataBound);
rptDtl.DataSource = Obj.GetDtlList(p1);
rptDtl.DataBind();
}
}
}
void rptDtl_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rpt = (Repeater)sender;
string dataMember = rpt.DataMember;
int count = rpt.Items.Count;
int splitIdx = dataMember.IndexOf(',');
int index = int.Parse(dataMember.Substring(0, splitIdx));
int p1 = int.Parse(dataMember.Substring(splitIdx + 1));
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Literal ltlTr1 = e.Item.FindControl("ltlTr1") as Literal;
if (ltlTr1 != null)
{
if (e.Item.ItemIndex > 0)
{
if ((index + 1) % 2 == 0)
ltlTr1.Text = "<tr class=\"trEven\" style=\"text-align:center;\"><td>";
else
ltlTr1.Text = "<tr style=\"text-align:center;\"><td>";
}
else
{
ltlTr1.Text = String.Empty;
}
}
}
if (e.Item.ItemType == ListItemType.Footer)
{
HtmlTableRow trTotal = e.Item.FindControl("trTotal") as HtmlTableRow;
if (trTotal != null && (index + 1) % 2 == 0)
{
trTotal.Attributes["class"] = "trEven";
}
Literal ltlTotal = e.Item.FindControl("ltlTotal") as Literal;
if (ltlTotal != null)
{
StringBuilder sb = new StringBuilder();
sb.Append("<tr");
if ((index + 1) % 2 == 0)
{
sb.Append(" class=\"trEven\"");
}
sb.AppendFormat("><td align=\"right\" colspan=\"{0}\">", gvData.Columns.Count + 2);
sb.AppendFormat("总计:{0}", Obj.GetDtlCount(p1));
ltlTotal.Text = sb.ToString();
}
}
}
}
public class Obj
{
int p1;
public int P1
{
get { return p1; }
set { p1 = value; }
}
string p2;
public string P2
{
get { return p2; }
set { p2 = value; }
}
public Obj(int p1, string p2)
{
this.p1 = p1;
this.p2 = p2;
}
public static List<Obj> GetObjList()
{
List<Obj> list = new List<Obj>();
list.Add(new Obj(1, "rerrteer"));
list.Add(new Obj(2, "rertrter"));
list.Add(new Obj(3, "resrrer"));
list.Add(new Obj(4, "rerrtrer"));
list.Add(new Obj(5, "reagdrer"));
list.Add(new Obj(6, "rerrter"));
list.Add(new Obj(7, "redfgrer"));
list.Add(new Obj(8, "rerfdger"));
list.Add(new Obj(9, "rerstrer"));
list.Add(new Obj(10, "rerer"));
list.Add(new Obj(11, "rezdfgrer"));
list.Add(new Obj(12, "rerer"));
list.Add(new Obj(13, "rerzdfger"));
list.Add(new Obj(14, "redgrer"));
list.Add(new Obj(15, "redgrer"));
return list;
}
public static List<Dtl> GetDtlList(int p1)
{
int count = 3;
if (p1 == 2)
{
count = 4;
}
List<Dtl> list = new List<Dtl>();
for (int i = 0; i < count; i++)
{
list.Add(new Dtl(i, p1));
}
return list;
}
public static int GetDtlSize(int p1)
{
return GetDtlList(p1).Count;
}
public static double GetDtlCount(int p1)
{
double count = 0;
foreach (Dtl d in GetDtlList(p1))
{
count += d.D3;
}
return count;
}
}
public class Dtl
{
string d1, d2;
public string D1
{
get { return d1; }
set { d1 = value; }
}
public string D2
{
get { return d2; }
set { d2 = value; }
}
double d3;
public double D3
{
get { return d3; }
set { d3 = value; }
}
public Dtl(int idx, int p1)
{
d1 = "d1" + p1;
d2 = "d2" + p1;
d3 = p1 * 1.725;
}
}