最近在公司碰到这样一个报表,这个报表需显示主表和细节表的资料并且统计细节表的某个栏位,而且还要分页显示,这个不是简单的单元格合并就能解决的问题,我曾试着合并单元格,但是分页不是用户想要的效果,所以我采用了一个怪异的方式解决了。效果如下图:
具体的实现我就不详细介绍了,把代码贴上来,供有相同需求的朋友参考吧。
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; } }