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

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 集合来定义子列,从而实现多表头的效果:

FineUI小技巧(7)多表头表格导出_第1张图片


///
/// 处理多表头的类
///
public  class  MultiHeaderTable
{
     // 包含 rowspan,colspan 的多表头,方便生成 HTML 的 table 标签
     public  List object []>> MultiTable =  new  List object []>>();
     // 最终渲染的列数组
     public  List Columns =  new  List();
 
 
     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( "" );
 
 
     sb.Append( "");
 
     foreach  (List< object []> rows  in  mht.MultiTable)
     {
         sb.Append( "
");
         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( "{3}" ,
                 rowspan != 1 ?  " rowspan=\""  + rowspan +  "\""  "" ,
                 colspan != 1 ?  " colspan=\""  + colspan +  "\""  "" ,
                 colspan != 1 ?  " style=\"text-align:center;\""  "" ,
                 column.HeaderText);
         }
         sb.Append( "
");
     }
 
 
     foreach  (GridRow row  in  grid.Rows)
     {
         sb.Append( "
");
 
         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( "
", html);
         }
 
         sb.Append( "
");
     }
 
     sb.Append( "
{0}
" );
 
     return  sb.ToString();
}

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

FineUI小技巧(7)多表头表格导出_第2张图片

转载自

Sanshi(Asp.Net控件)

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

你可能感兴趣的:(FineUI小技巧(7)多表头表格导出)