FineUI小技巧(7)多表头表格导出

来源:互联网 发布:python item 编辑:程序博客网 时间:2024/05/28 06:07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

在 ASPX 中,我们通过 GroupField 列来定义多表头,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<f:Grid ID="Grid1" Title="表格" EnableCollapse="true" ShowBorder="true" ShowHeader="true" Width="800px"
    runat="server" DataKeyNames="Id,Name">
    <Columns>
        <f:TemplateField ColumnID="tfNumber" Width="60px">
            <ItemTemplate>
                <span id="spanNumber" runat="server"><%# Container.DataItemIndex + 1 %></span>
            </ItemTemplate>
        </f:TemplateField>
        <f:GroupField EnableLock="true" HeaderText="分组一" TextAlign="Center">
            <Columns>
                <f:BoundField Width="100px" DataField="Name" DataFormatString="{0}" HeaderText="姓名" />
                <f:TemplateField ColumnID="tfGender" Width="80px" HeaderText="性别" TextAlign="Center">
                    <ItemTemplate>
                        <asp:Label ID="labGender" runat="server" Text='<%# GetGender(Eval("Gender")) %>'></asp:Label>
                    </ItemTemplate>
                </f:TemplateField>
                <f:GroupField EnableLock="true" HeaderText="考试成绩" TextAlign="Center">
                    <Columns>
                        <f:BoundField EnableLock="true" Width="80px" DataField="ChineseScore" SortField="ChineseScore" HeaderText="语文成绩"
                            TextAlign="Center" />
                        <f:BoundField EnableLock="true" Width="80px" DataField="MathScore" SortField="MathScore" HeaderText="数学成绩"
                            TextAlign="Center" />
                        <f:BoundField EnableLock="true" Width="80px" DataField="TotalScore" SortField="TotalScore" HeaderText="总成绩"
                            TextAlign="Center" />
                    </Columns>
                </f:GroupField>
            </Columns>
        </f:GroupField>
        <f:BoundField ExpandUnusedSpace="True" DataField="Major" HeaderText="所学专业" />
        <f:BoundField Width="100px" DataField="LogTime" DataFormatString="{0:yy-MM-dd}" HeaderText="注册日期" />
    </Columns>
</f:Grid>

这是一个树状的结构,通过 GroupField 的 Columns 集合来定义子列,从而实现多表头的效果:


/// <summary>
/// 处理多表头的类
/// </summary>
public class MultiHeaderTable
{
    // 包含 rowspan,colspan 的多表头,方便生成 HTML 的 table 标签
    public List<List<object[]>> MultiTable = new List<List<object[]>>();
    // 最终渲染的列数组
    public List<GridColumn> Columns = new List<GridColumn>();
 
 
    public void ResolveMultiHeaderTable(GridColumnCollection columns)
    {
        List<object[]> row = new List<object[]>();
        foreach (GridColumn column in columns)
        {
            object[] cell = new object[4];
            cell[0] = 1;    // rowspan
            cell[1] = 1;    // colspan
            cell[2] = column;
            cell[3] = null;
 
            row.Add(cell);
        }
 
        ResolveMultiTable(row, 0);
 
        ResolveColumns(row);
    }
 
    private void ResolveColumns(List<object[]> row)
    {
        foreach (object[] cell in row)
        {
            GroupField groupField = cell[2] as GroupField;
            if (groupField != null && groupField.Columns.Count > 0)
            {
                List<object[]> subrow = new List<object[]>();
                foreach (GridColumn column in groupField.Columns)
                {
                    subrow.Add(new object[]
                    {
                        1,
                        1,
                        column,
                        groupField
                    });
                }
 
                ResolveColumns(subrow);
            }
            else
            {
                Columns.Add(cell[2] as GridColumn);
            }
        }
 
    }
 
    private void ResolveMultiTable(List<object[]> row, int level)
    {
        List<object[]> nextrow = new List<object[]>();
 
        foreach (object[] cell in row)
        {
            GroupField groupField = cell[2] as GroupField;
            if (groupField != null && groupField.Columns.Count > 0)
            {
                // 如果当前列包含子列,则更改当前列的 colspan,以及增加父列(向上递归)的colspan
                cell[1] = Convert.ToInt32(groupField.Columns.Count);
                PlusColspan(level - 1, cell[3] as GridColumn,groupField.Columns.Count - 1);
 
                foreach (GridColumn column in groupField.Columns)
                {
                    nextrow.Add(new object[]
                    {
                        1,
                        1,
                        column,
                        groupField
                    });
                }
            }
        }
 
        MultiTable.Add(row);
 
        // 如果当前下一行,则增加上一行(向上递归)中没有子列的列的 rowspan
        if (nextrow.Count > 0)
        {
            PlusRowspan(level);
 
            ResolveMultiTable(nextrow, level + 1);
        }
    }
 
    private void PlusRowspan(int level)
    {
        if (level < 0)
        {
            return;
        }
 
        foreach (object[] cells in MultiTable[level])
        {
            GroupField groupField = cells[2] as GroupField;
            if (groupField != null && groupField.Columns.Count > 0)
            {
                // ...
            }
            else
            {
                cells[0] = Convert.ToInt32(cells[0]) + 1;
            }
        }
 
        PlusRowspan(level - 1);
    }
 
    private void PlusColspan(int level, GridColumn parent, int plusCount)
    {
        if (level < 0)
        {
            return;
        }
 
        foreach (object[] cells in MultiTable[level])
        {
            GridColumn column = cells[2] as GridColumn;
            if (column == parent)
            {
                cells[1] = Convert.ToInt32(cells[1]) + plusCount;
 
                PlusColspan(level - 1, cells[3] as GridColumn, plusCount);
            }
        }
    }
 
}

 

其实主要的逻辑就上面提到的两点,然后需要好几个递归函数来一块完成任务。

 

导出的代码调用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
protected void Button1_Click(object sender, EventArgs e)
{
    Response.ClearContent();
    Response.AddHeader("content-disposition""attachment; filename=myexcel.xls");
    Response.ContentType = "application/excel";
    Response.ContentEncoding = System.Text.Encoding.UTF8;
    Response.Write(GetGridTableHtml(Grid1));
    Response.End();
}
 
private string GetGridTableHtml(Grid grid)
{
    StringBuilder sb = new StringBuilder();
 
    MultiHeaderTable mht = new MultiHeaderTable();
    mht.ResolveMultiHeaderTable(Grid1.Columns);
 
 
    sb.Append("<meta http-equiv=\"content-type\" content=\"application/excel; charset=UTF-8\"/>");
 
 
    sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");
 
    foreach (List<object[]> rows in mht.MultiTable)
    {
        sb.Append("<tr>");
        foreach (object[] cell in rows)
        {
            int rowspan = Convert.ToInt32(cell[0]);
            int colspan = Convert.ToInt32(cell[1]);
            GridColumn column = cell[2] as GridColumn;
 
            sb.AppendFormat("<th{0}{1}{2}>{3}</th>",
                rowspan != 1 ? " rowspan=\"" + rowspan + "\"" "",
                colspan != 1 ? " colspan=\"" + colspan + "\"" "",
                colspan != 1 ? " style=\"text-align:center;\"" "",
                column.HeaderText);
        }
        sb.Append("</tr>");
    }
 
 
    foreach (GridRow row in grid.Rows)
    {
        sb.Append("<tr>");
 
        foreach (GridColumn column in mht.Columns)
        {
            string html = row.Values[column.ColumnIndex].ToString();
 
            if (column.ColumnID == "tfNumber")
            {
                html = (row.FindControl("spanNumber"as System.Web.UI.HtmlControls.HtmlGenericControl).InnerText;
            }
            else if (column.ColumnID == "tfGender")
            {
                html = (row.FindControl("labGender"as AspNet.Label).Text;
            }
 
 
            sb.AppendFormat("<td>{0}</td>", html);
        }
 
        sb.Append("</tr>");
    }
 
    sb.Append("</table>");
 
    return sb.ToString();
}

最终导出的文件结构如下所示:

转载自

Sanshi(Asp.Net控件)

转载地址:http://www.cnblogs.com/sanshi/p/4104411.html

0 0
原创粉丝点击