GridView多表头固定+分组+总计

  一直在网上找资料来弄个固定表头的东西 有时也想根据有字段来对数据进行分组。

 完成了一个项目也把一些经常见到的需求提炼出了一个还比较可以的解决方案。

常见需求:

   1、列表显示数据

   2、滚动滚动条时表头固定

   3、按要求将数据分组并计算求和

这些问题在财务系统中经常遇到相比在其他行业也有类似情况,今天下午整理了下资料,来出来和大家分享。

  效果图1:

 

 效果图2 :含总计行

 

代码:

  页面类:

代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>GridView固定表头+分组+固定</title>
<style type="text/css">
.staicTitlteDiv{
WIDTH: 1000px;
height:500px ;
OVERFLOW: scroll;
SCROLLBAR
-FACE-COLOR: EAECEC;
SCROLLBAR
-HIGHLIGHT-COLOR: EAECEC;
SCROLLBAR
-SHADOW-COLOR: BLACK;
SCROLLBAR
-3DLIGHT-COLOR: EAECEC;
SCROLLBAR
-ARROW-COLOR: EAECEC;
SCROLLBAR
-TRACK-COLOR: FFFFFF;
SCROLLBAR
-DARKSHADOW-COLOR: EAECEC;

}
.fixedHeaderTr
{
position:relative;
border:
0;
top:expression(
this.offsetParent.scrollTop);

}
th{
position:relative;
background
-color: Beige;
top:expression(
this.offsetParent.scrollTop);
}
</style>

</head>
<body style="text-align:center">
<form id="form1" runat="server" >
<div class="staicTitlteDiv">
<asp:GridView ID="GridView1" runat="server">
<HeaderStyle CssClass="fixedHeaderTr" BorderColor="Beige" />
</asp:GridView>
</div>
</form>
</body>
</html>

 后置代码:

代码
1 using System;
2  using System.Collections;
3  using System.Configuration;
4  using System.Data;
5  using System.Linq;
6  using System.Web;
7  using System.Web.Security;
8 using System.Web.UI;
9 using System.Web.UI.HtmlControls;
10 using System.Web.UI.WebControls;
11 using System.Web.UI.WebControls.WebParts;
12 using System.Xml.Linq;
13 using System.Collections.Generic;
14 using System.Linq;
15 public partial class Default2 : System.Web.UI.Page
16 {
17
18 protected void Page_Load(object sender, EventArgs e)
19 {
20 if (!IsPostBack)
21 {
22 GridView1.RowDataBound += new GridViewRowEventHandler(GridView1_RowDataBound);
23 GridView1.DataBound += new EventHandler(GridView_DataBound);
24 GridView1DataBind();
25
26
27 }
28 }
29 void GridView1DataBind()
30 {
31 DataTable table = new DataTable();
32 table.Columns.Add("class", typeof(string)).SetOrdinal(0);
33 table.Columns.Add("student", typeof(string)).SetOrdinal(1);
34 table.Columns.Add("Languages", typeof(Double)).SetOrdinal(2);
35 table.Columns.Add("Rate1", typeof(Double)).SetOrdinal(3);
36 table.Columns.Add("Mathematics", typeof(Double)).SetOrdinal(4);
37 table.Columns.Add("Rate2", typeof(Double)).SetOrdinal(5);
38 table.Columns.Add("English", typeof(Double)).SetOrdinal(6);
39 table.Columns.Add("Rate3", typeof(Double)).SetOrdinal(7);
40 table.Columns.Add("Other", typeof(Double)).SetOrdinal(8);
41 table.Columns.Add("TotalScore", typeof(Double), "ISNULL(Languages,0)+ISNULL(Mathematics,0)+ISNULL(English,0)+ISNULL(Other,0)").SetOrdinal(9);
42
43 table.Columns[3].Expression = "Languages/TotalScore";
44 table.Columns[5].Expression ="Mathematics/TotalScore";
45 table.Columns[7].Expression = "English/TotalScore";
46 Random random = new Random();
47 for (int i = 0; i < 100; i++)
48 {
49 DataRow row = table.NewRow();
50 row["student"] = "学生" + i;
51 row["class"] = "班级" + random.Next(0, 10);
52 row["Languages"] = random.Next(0, 151);
53 row["Mathematics"] = random.Next(0, 151);
54 row["English"] = random.Next(0, 151);
55 row["Other"] = random.Next(0, 150*3+1);
56 table.Rows.Add(row);
57 }
58
59 //GridView1.DataSource =GridViewGroup.AddGurop(table, "class");
60 GridView1.DataSource = GridViewGroup.AddGurop(table, "class", "Languages#Mathematics#English#Other");
61 GridView1.DataBind();
62
63 }
64 void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
65 {
66 if (e.Row.RowType == DataControlRowType.Header)
67 {
68 string header = "班级#学生#其中 语文 成绩,比例#其中 数学 成绩,比例#其中 英语 成绩,比例#其中 &nbsp; 其他3科#总成绩";
69 AndyGridViewTHeaderHepler help = new AndyGridViewTHeaderHepler();
70 e.Row.CssClass = "fixedHeaderTr";
71
72 e.Row.BackColor = System.Drawing.Color.Beige;
73 help.SplitTableHeader(e.Row, header);
74 }
75 else
76 {
77 e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='White'");
78 e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor=\"" + "#E7E7FF" + "\"");
79
80 }
81 }
82
83 protected void GridView_DataBound(object sender, EventArgs e)
84 {
85 int index = -1;
86 int startGroupIndex = 0;
87 foreach (GridViewRow row in GridView1.Rows)
88 {
89 index++;
90
91 if (index > 0 && (row.Cells[0].Text.ToString().Trim() == "" || row.Cells[0].Text.ToString().Trim() == "&nbsp;"))
92 {
93 row.Cells[0].Text = "小计";// GridView1.Rows[startGroupIndex].Cells[0].Text;
94 row.Attributes.Add("style", "background-color: #F2F2F2; font-weight: bold;font-variant: normal; color: #000000;text-align:center;");
95 row.Attributes.Remove("onmouseout");
96 row.Attributes.Remove("onmouseover");
97 GridViewGroup.GroupRow(GridView1, index, 0, 2);
98 GridViewGroup.GropCell(GridView1, 0, startGroupIndex, index - 1);
99 startGroupIndex = index + 1;
100 }
101 }
102 GridViewRow sumRow = GridView1.Rows[index];
103 sumRow.Attributes.Add("style", "background-color: #EAEAEA;font-weight: bold;font-variant: normal;color: #000000;text-align: center;");
104 sumRow.Attributes.Remove("onmouseout");
105 sumRow.Attributes.Remove("onmouseover");
106 GridViewGroup.GroupRow(GridView1, index, 0, 2);
107 }
108 }
109

 3.多表头帮助类(来自网络)

AndyGridViewTHeaderHepler.cs
1
2 using System;
3 using System.Data;
4 using System.Configuration;
5 using System.Web;
6 using System.Web.Security;
7 using System.Web.UI;
8 using System.Web.UI.WebControls;
9 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using System.Collections.Generic;
12 using System.Collections;
13
14
15 //-----------------------------------------------------------------------------------
16 //
17 // Created: 23:07 2008/9/28 Author: Andy Lu
18 // File: AndyGridViewTHeaderHepler.cs
19 // Description: 动态生成复合表头帮助类
20 // 相邻父列头之间用'#'分隔,父列头与子列头用空格(' ')分隔,相邻子列头用逗号分隔(',').
21 // 两行:序号#分公司#组别#本日成功签约单数 预警,续约,流失,合计#累计成功签约单数 预警,续约,流失,合计#任务数#完成比例#排名
22 // 三行:等级#级别#上期结存 件数, 重量,比例#本期调入 收购调入 件数,重量,比例#本期发出 车间投料 件数,重量,比例#本期发出 产品外销百分比 件数,重量,比例#平均值
23 // 三行时请注意:列头要重复
24 //
25 //-----------------------------------------------------------------------------------
26 public class AndyGridViewTHeaderHepler
27 {
28 public AndyGridViewTHeaderHepler()
29 {
30 //
31 // TODO: Add constructor logic here
32 //
33 }
34 /**/
35 /// <summary>
36 /// 重写表头
37 /// </summary>
38 /// <param name="targetHeader">目标表头</param>
39 /// <param name="newHeaderNames">新表头</param>
40 /// <remarks>
41 /// </remarks>
42 public void SplitTableHeader(GridViewRow targetHeader, string newHeaderNames)
43 {
44 TableCellCollection tcl = targetHeader.Cells; //获得表头元素的实例
45 tcl.Clear(); //清除元素
46 int row = GetRowCount(newHeaderNames);
47 int col = GetColCount(newHeaderNames);
48 string[,] nameList = ConvertList(newHeaderNames, row, col);
49 int RowSpan = 0;
50 int ColSpan = 0;
51 for (int k = 0; k < row; k++)
52 {
53 string LastFName = "";
54 for (int i = 0; i < col; i++)
55 {
56 if (LastFName == nameList[i, k] && k != row - 1)
57 {
58 LastFName = nameList[i, k];
59 continue;
60 }
61 else
62 {
63 LastFName = nameList[i, k];
64 }
65 int bFlag = IsVisible(nameList, k, i, LastFName);
66 switch (bFlag)
67 {
68 case 0:
69 break;
70 case 1:
71 RowSpan = GetSpanRowCount(nameList, row, k, i);
72 ColSpan = GetSpanColCount(nameList, row, col, k, i);
73 tcl.Add(new TableHeaderCell()); //添加表头控件
74 tcl[tcl.Count - 1].RowSpan = RowSpan;
75 tcl[tcl.Count - 1].ColumnSpan = ColSpan;
76 tcl[tcl.Count - 1].HorizontalAlign = HorizontalAlign.Center;
77 tcl[tcl.Count - 1].Text = LastFName;
78 break;
79 case -1:
80 string[] EndColName = LastFName.Split(new char[] { ',' });
81 foreach (string eName in EndColName)
82 {
83 tcl.Add(new TableHeaderCell()); //添加表头控件
84 tcl[tcl.Count - 1].HorizontalAlign = HorizontalAlign.Center;
85 tcl[tcl.Count - 1].Text = eName;
86 }
87 break;
88 }
89 }
90 if (k != row - 1)
91 { //不是起始行,加入新行标签
92 tcl[tcl.Count - 1].Text = tcl[tcl.Count - 1].Text + "</th></tr><tr class=\"" + targetHeader.CssClass + "\">";
93 }
94 }
95 }
96 /**/
97 /// <summary>
98 /// 重写表头
99 /// </summary>
100 /// <param name="targetHeader">目标表头</param>
101 /// <param name="newHeaderNames">新表头</param>
102 /// <remarks>
103 /// </remarks>
104 public void SplitTableHeader(DataGridItem targetHeader, string newHeaderNames)
105 {
106 TableCellCollection tcl = targetHeader.Cells; //获得表头元素的实例
107 tcl.Clear(); //清除元素
108 int row = GetRowCount(newHeaderNames);
109 int col = GetColCount(newHeaderNames);
110 string[,] nameList = ConvertList(newHeaderNames, row, col);
111 int RowSpan = 0;
112 int ColSpan = 0;
113 for (int k = 0; k < row; k++)
114 {
115 string LastFName = "";
116 for (int i = 0; i < col; i++)
117 {
118 if (LastFName == nameList[i, k] && k != row - 1)
119 {
120 LastFName = nameList[i, k];
121 continue;
122 }
123 else
124 {
125 LastFName = nameList[i, k];
126 }
127 int bFlag = IsVisible(nameList, k, i, LastFName);
128 switch (bFlag)
129 {
130 case 0:
131 break;
132 case 1:
133 RowSpan = GetSpanRowCount(nameList, row, k, i);
134 ColSpan = GetSpanColCount(nameList, row, col, k, i);
135 tcl.Add(new TableHeaderCell()); //添加表头控件
136 tcl[tcl.Count - 1].RowSpan = RowSpan;
137 tcl[tcl.Count - 1].ColumnSpan = ColSpan;
138 tcl[tcl.Count - 1].HorizontalAlign = HorizontalAlign.Center;
139 tcl[tcl.Count - 1].Text = LastFName;
140 break;
141 case -1:
142 string[] EndColName = LastFName.Split(new char[] { ',' });
143 foreach (string eName in EndColName)
144 {
145 tcl.Add(new TableHeaderCell()); //添加表头控件
146 tcl[tcl.Count - 1].HorizontalAlign = HorizontalAlign.Center;
147 tcl[tcl.Count - 1].Text = eName;
148 }
149 break;
150 }
151 }
152 if (k != row - 1)
153 { //不是起始行,加入新行标签
154 tcl[tcl.Count - 1].Text = tcl[tcl.Count - 1].Text + "</th></tr><tr class=\"" + targetHeader.CssClass + "\">";
155 }
156 }
157 }
158 /**/
159 /// <summary>
160 /// 如果上一行已经输出和当前内容相同的列头,则不显示
161 /// </summary>
162 /// <param name="ColumnList">表头集合</param>
163 /// <param name="rowIndex">行索引</param>
164 /// <param name="colIndex">列索引</param>
165 /// <returns>1: 显示,-1:含','分隔符,0:不显示</returns>
166 private int IsVisible(string[,] ColumnList, int rowIndex, int colIndex, string CurrName)
167 {
168 if (rowIndex != 0)
169 {
170 if (ColumnList[colIndex, rowIndex - 1] == CurrName)
171 {
172 return 0;
173 }
174 else
175 {
176 if (ColumnList[colIndex, rowIndex].Contains(","))
177 {
178 return -1;
179 }
180 else
181 {
182 return 1;
183 }
184 }
185 }
186 return 1;
187 }
188 /**/
189 /// <summary>
190 /// 取得和当前索引行及列对应的下级的内容所跨的行数
191 /// </summary>
192 /// <param name="ColumnList"& gt;表头集合</param>
193 /// <param name="row"& gt;行数</param>
194 /// <param name="rowIndex"& gt;行索引</param>
195 /// <param name="colIndex"& gt;列索引</param>
196 /// <returns> 行数</returns>
197 private int GetSpanRowCount(string[,] ColumnList, int row, int rowIndex, int colIndex)
198 {
199 string LastName = "";
200 int RowSpan = 1;
201 for (int k = rowIndex; k < row; k++)
202 {
203 if (ColumnList[colIndex, k] == LastName)
204 {
205 RowSpan++;
206 }
207 else
208 {
209 LastName = ColumnList[colIndex, k];
210 }
211 }
212 return RowSpan;
213 }
214 /**/
215 /// <summary>
216 /// 取得和当前索引行及列对应的下级的内容所跨的列数
217 /// </summary>
218 /// <param name="ColumnList"& gt;表头集合</param>
219 /// <param name="row"& gt;行数</param>
220 /// <param name="col"& gt;列数</param>
221 /// <param name="rowIndex"& gt;行索引</param>
222 /// <param name="colIndex"& gt;列索引</param>
223 /// <returns>列数< /returns>
224 private int GetSpanColCount(string[,] ColumnList, int row, int col, int rowIndex, int colIndex)
225 {
226 string LastName = ColumnList[colIndex, rowIndex];
227 int ColSpan = ColumnList[colIndex, row - 1].Split(new char[] { ',' }).Length;
228 ColSpan = ColSpan == 1 ? 0 : ColSpan;
229 for (int i = colIndex + 1; i < col; i++)
230 {
231 if (ColumnList[i, rowIndex] == LastName)
232 {
233 ColSpan += ColumnList[i, row - 1].Split(new char[] { ',' }).Length;
234 }
235 else
236 {
237 LastName = ColumnList[i, rowIndex];
238 break;
239 }
240 }
241 return ColSpan;
242 }
243 /**/
244 /// <summary>
245 /// 将已定义的表头保存到数组
246 /// </summary>
247 /// <param name="newHeaders"& gt;新表头</param>
248 /// <param name="row"& gt;行数</param>
249 /// <param name="col"& gt;列数</param>
250 /// <returns>表头数组</returns>
251 private string[,] ConvertList(string newHeaders, int row, int col)
252 {
253 string[] ColumnNames = newHeaders.Split(new char[] { '#' });
254 string[,] news = new string[col, row];
255 string Name = "";
256 for (int i = 0; i < col; i++)
257 {
258 string[] CurrColNames = ColumnNames[i].ToString().Split(new char[] { ' ' });
259 for (int k = 0; k < row; k++)
260 {
261 if (CurrColNames.Length - 1 >= k)
262 {
263 if (CurrColNames[k].Contains(","))
264 {
265 if (CurrColNames.Length != row)
266 {
267 if (Name == "")
268 {
269 news[i, k] = news[i, k - 1];
270 Name = CurrColNames[k].ToString();
271 }
272 else
273 {
274 news[i, k + 1] = Name;
275 Name = "";
276 }
277 }
278 else
279 {
280 news[i, k] = CurrColNames[k].ToString();
281 }
282 }
283 else
284 {
285 news[i, k] = CurrColNames[k].ToString();
286 }
287 }
288 else
289 {
290 if (Name == "")
291 {
292 news[i, k] = news[i, k - 1];
293 }
294 else
295 {
296 news[i, k] = Name;
297 Name = "";
298 }
299 }
300 }
301 }
302 return news;
303 }
304 /**/
305 /// <summary>
306 /// 取得复合表头的行数
307 /// </summary>
308 /// <param name="newHeaders"& gt;新表头</param>
309 /// <returns>行数< /returns>
310 private int GetRowCount(string newHeaders)
311 {
312 string[] ColumnNames = newHeaders.Split(new char[] { '#' });
313 int Count = 0;
314 foreach (string name in ColumnNames)
315 {
316 int TempCount = name.Split(new char[] { ' ' }).Length;
317 if (TempCount > Count)
318 Count = TempCount;
319 }
320 return Count;
321 }
322 /**/
323 /// <summary>
324 /// 取得复合表头的列数
325 /// </summary>
326 /// <param name="newHeaders"& gt;新表头</param>
327 /// <returns>列数< /returns>
328 private int GetColCount(string newHeaders)
329 {
330 return newHeaders.Split(new char[] { '#' }).Length;
331 }
332
333 }
334
335
336

4. 分组 汇总 总计帮助类

GridViewGroup.cs
1 using System;
2 using System.Data;
3 using System.Configuration;
4 using System.Linq;
5 using System.Web;
6 using System.Web.Security;
7 using System.Web.UI;
8 using System.Web.UI.HtmlControls;
9 using System.Web.UI.WebControls;
10 using System.Web.UI.WebControls.WebParts;
11 using System.Xml.Linq;
12 using System.Collections.Generic;
13
14 /// <summary>
15 ///GridViewGroup 的摘要说明
16 /// </summary>
17 public class GridViewGroup
18 {
19 public GridViewGroup()
20 {
21 //
22 //TODO: 在此处添加构造函数逻辑
23 //
24 }
25 /// <summary>
26 /// 向DataTable中添加 行分组汇总列
27 /// </summary>
28 /// <param name="olDtable">DataTable</param>
29 /// <param name="bjName">分组列</param>
30 /// <param name="numColumsStr">需要计算求和的列,用#分割</param>
31 /// <returns></returns>
32 public static DataTable AddGurop(DataTable olDtable, string bjName, string numColumsStr)
33 {
34
35 //为null 或 只有一条记录对于分组来说无意义
36 if (olDtable == null)
37 {
38 return olDtable;
39 }
40 DataTable table = TableSort(olDtable, bjName);
41 Dictionary<int, DataRow> rows = new Dictionary<int, DataRow>();//存放汇总行
42
43 IList<string> numColumns=new List<string>();
44 if (numColumsStr == null)
45 {
46 numColumns = GetNumColumns(table);
47 }
48 else
49 {
50 string[] columns = numColumsStr.Split('#');
51 foreach (string str in columns)
52 {
53 numColumns.Add(str);
54 }
55 }
56
57 string prevDept = table.Rows[0][bjName].ToString();//
58 int NoOwn = 0;//同组项的第一行记录的位置
59 int index = -1;//索引
60 foreach (DataRow item in table.Rows)
61 {
62 index++;//当前行索引
63 //如果相邻两行 分组标记相同 则继续寻找下行,否则该行为同组的最后一行。进行数据处理
64 //item[bjName].ToString() == prevDept 表示为同行 则继续比较下一行
65 if (item[bjName].ToString() == prevDept && index != table.Rows.Count - 1)
66 {
67 continue;
68 }
69 else if (index == table.Rows.Count - 1)
70 {
71 if (item[bjName].ToString() != prevDept)
72 {
73 DataRow row = CreateGroupRow(table, numColumns, NoOwn, index);
74 rows.Add(index + rows.Count, row);
75
76 DataRow row2 = table.NewRow();
77 foreach (string columnName in numColumns)
78 {
79 row2[columnName] = item[columnName];
80 }
81 rows.Add(index + rows.Count + 1, row2);
82 }
83 else
84 {
85 DataRow row = CreateGroupRow(table, numColumns, NoOwn, index);
86 rows.Add(index + rows.Count + 1, row);
87 }
88
89 }
90 else
91 {
92 prevDept = item[bjName].ToString();//当前分组标记
93 DataRow row = CreateGroupRow(table, numColumns, NoOwn, index);
94 NoOwn = index;
95 rows.Add(index + rows.Count, row);
96 }
97 }
98
99 DataRow sumRow = CreateSumRow(table, rows, numColumns);
100
101 foreach (int key in rows.Keys)
102 {
103 table.Rows.InsertAt(rows[key], key);
104 }
105
106 table.Rows.Add(sumRow);
107 return table;
108 }
109 /// <summary>
110 /// 向DataTable中添加 行分组汇总列
111 /// </summary>
112 /// <param name="olDtable">DataTable</param>
113 /// <param name="bjName">分组列</param>
114 /// <returns></returns>
115 public static DataTable AddGurop(DataTable olDtable, string bjName)
116 {
117
118 //为null 或 只有一条记录对于分组来说无意义
119 if (olDtable == null)
120 {
121 return olDtable;
122 }
123 DataTable table = TableSort(olDtable, bjName);
124 Dictionary<int, DataRow> rows = new Dictionary<int, DataRow>();//存放汇总行
125 IList<string> numColumns =GetNumColumns(table);
126 string prevDept = table.Rows[0][bjName].ToString();//
127 int NoOwn = 0;//同组项的第一行记录的位置
128 int index = -1;//索引
129 foreach (DataRow item in table.Rows)
130 {
131 index++;//当前行索引
132 //如果相邻两行 分组标记相同 则继续寻找下行,否则该行为同组的最后一行。进行数据处理
133 //item[bjName].ToString() == prevDept 表示为同行 则继续比较下一行
134 if (item[bjName].ToString() == prevDept && index != table.Rows.Count - 1)
135 {
136 continue;
137 }
138 else if (index == table.Rows.Count - 1)
139 {
140 if (item[bjName].ToString() != prevDept)
141 {
142 DataRow row = CreateGroupRow(table, numColumns, NoOwn, index);
143 rows.Add(index + rows.Count, row);
144
145 DataRow row2 = table.NewRow();
146 foreach (string columnName in numColumns)
147 {
148 row2[columnName] = item[columnName];
149 }
150 rows.Add(index + rows.Count + 1, row2);
151 }
152 else
153 {
154 DataRow row = CreateGroupRow(table, numColumns, NoOwn, index);
155 rows.Add(index + rows.Count + 1, row);
156 }
157
158 }
159 else
160 {
161 prevDept = item[bjName].ToString();//当前分组标记
162 DataRow row = CreateGroupRow(table, numColumns, NoOwn, index);
163 NoOwn = index;
164 rows.Add(index + rows.Count, row);
165 }
166 }
167
168 DataRow sumRow = CreateSumRow(table, rows, numColumns);
169
170 foreach (int key in rows.Keys)
171 {
172 table.Rows.InsertAt(rows[key], key);
173 }
174
175 table.Rows.Add(sumRow);
176 return table;
177 }
178
179 /// <summary>
180 /// 生成总计行
181 /// </summary>
182 /// <param name="table">DataTalbe</param>
183 /// <param name="rows">汇总行集合</param>
184 /// <param name="numColumns">累计列</param>
185 /// <returns>总计行</returns>
186 private static DataRow CreateSumRow(DataTable table, Dictionary<int, DataRow> rows, IList<string> numColumns)
187 {
188 DataRow sumRow = table.NewRow();
189 sumRow[0] = "合计";
190 foreach (string columnName in numColumns)
191 {
192 foreach (int key in rows.Keys)
193 {
194 object count = sumRow[columnName];//汇总行 列值
195 //如果值为null 或 "" 则默认为 0
196 if (count == null || count.ToString().Trim() == "")
197 {
198 count = 0;
199 }
200 sumRow[columnName] = decimal.Parse(count.ToString()) + decimal.Parse(rows[key][columnName].ToString());//累加
201 }
202
203 }
204 return sumRow;
205 }
206
207 private static IList<string> GetNumColumns(DataTable table)
208 {
209 IList<string> numColumns = new List<string>();//存放数字行
210 foreach (DataColumn column in table.Columns)
211 {
212 if (column.DataType == typeof(Decimal) || column.DataType == typeof(Int32)
213 || column.DataType == typeof(Int64) | column.DataType == typeof(float)
214 || column.DataType == typeof(Int64) | column.DataType == typeof(Double)
215 )
216 {
217 numColumns.Add(column.ColumnName);
218 }
219 }
220 return numColumns;
221 }
222 /// <summary>
223 /// 将dataTable排序
224 /// </summary>
225 /// <param name="olDtable">DataTable</param>
226 /// <param name="bjName">排序字段</param>
227 /// <returns></returns>
228 public static DataTable TableSort(DataTable olDtable, string bjName)
229 {
230 DataTable table = olDtable.Clone();
231 DataRow[] sortRows = olDtable.Select(null, bjName);
232 foreach (DataRow item in sortRows)
233 {
234 table.ImportRow(item);
235 }
236 return table;
237 }
238 /// <summary>
239 /// 生成汇总行
240 /// </summary>
241 /// <param name="table">分组表</param>
242 /// <param name="numColumns">需要汇总的列</param>
243 /// <param name="NoOwn">开始行</param>
244 /// <param name="index">结束行</param>
245 /// <returns>汇总行</returns>
246 private static DataRow CreateGroupRow(DataTable table, IList<string> numColumns, int startRowIndex, int endRowIndex)
247 {
248 DataRow row = table.NewRow();//汇总行
249 //从同组项的第一行记录的位置 到 同组的最后一行
250 for (int i = startRowIndex; i < endRowIndex + 1; i++)
251 {
252
253 foreach (string columnName in numColumns)
254 {
255
256 object count = row[columnName];//汇总行 列值
257 object tempt = table.Rows[i][columnName];//当前行 列值
258 //如果值为null 或 "" 则默认为 0
259 if (count == null || count.ToString().Trim() == "")
260 {
261 count = 0;
262 }
263 if (tempt == null || tempt.ToString().Trim() == "")
264 {
265 tempt = 0;
266 }
267 row[columnName] = decimal.Parse(count.ToString()) + decimal.Parse(tempt.ToString());//累加
268 }
269 }
270 return row;
271 }
272
273 /// <summary>
274 /// 合并单元格 合并一行中的几列
275 /// </summary>
276 /// <param name="GridView1">GridView对象</param>
277 /// <param name="rows">行索引</param>
278 /// <param name="sCol">开始列</param>
279 /// <param name="eCol">结束列</param>
280 public static void GroupRow(GridView gridView, int rows, int sCol, int eCol)
281 {
282 TableCell oldTc = gridView.Rows[rows].Cells[sCol];
283 for (int i = 1; i < eCol - sCol; i++)
284 {
285 TableCell tc = gridView.Rows[rows].Cells[i + sCol];   //Cells[0]就是你要合并的列
286 tc.Visible = false;
287 if (oldTc.ColumnSpan == 0)
288 {
289 oldTc.ColumnSpan = 1;
290 }
291 oldTc.ColumnSpan++;
292 oldTc.VerticalAlign = VerticalAlign.Middle;
293 }
294 }
295 /// <summary>
296 /// 合并列
297 /// </summary>
298 /// <param name="gv">gridview对象</param>
299 /// <param name="cells">列索引</param>
300 /// <param name="sRow">合并列开始位置</param>
301 /// <param name="eRow">合并列结束位置</param>
302 public static void GropCell(GridView gv, int cells, int sRow, int eRow)
303 {
304 TableCell tc = gv.Rows[sRow].Cells[cells];
305 tc.RowSpan = eRow - sRow + 1;
306 for (int i = sRow + 1; i <= eRow; i++)
307 {
308 gv.Rows[i].Cells[cells].Visible = false;
309 }
310 }
311 }
312

  转载注明出处:http://www.cnblogs.com/howDo/articles/StaticGridViewHeader.html

源代码下载:https://files.cnblogs.com/howDo/StaticTitle.rar

原文地址:https://www.cnblogs.com/howDo/p/StaticGridViewHeader.html