一个比较麻烦的报表

      最近在公司碰到这样一个报表,这个报表需显示主表和细节表的资料并且统计细节表的某个栏位,而且还要分页显示,这个不是简单的单元格合并就能解决的问题,我曾试着合并单元格,但是分页不是用户想要的效果,所以我采用了一个怪异的方式解决了。效果如下图:

具体的实现我就不详细介绍了,把代码贴上来,供有相同需求的朋友参考吧。

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;
    }
}
posted @ 2009-08-12 13:25  known  阅读(797)  评论(4编辑  收藏  举报