数据交叉表的实现(2):通过组建Axes轴和Cell数组来建立数据交叉表模型
这篇距离上篇已经有些时日了,最近也比较忙,一直没有好好的整理
楼下有人要代码,我就发出来把。顺便做个简单的介绍
模型的建立
横轴:
竖轴:
因为两个轴是一样的,那么我们放在一起来讲
首先一个轴应该包含哪些信息呢?
1:轴名称
2:Positon集合(用于存放真正的维度信息)
每个轴都有若干个Position 一个Position代表一个维度,Position里面是Member的结合(也就是维度数据的集合)--如下图所示:
数据CellSet:
CellSet相对前面的概念来说就比较简单了,Cellset就是存放数据的容器了
其中一个单元格就是一个Cell
我们还是来看一下代码把
数据绑定的部分
1 绑定数据#region 绑定数据
2 private DataView _dataView;
3 public override void DataBind()
4 {
5 // Load the data 其中dataSource是已经绑定的数据源
6 if (_dataSource != null)
7 {
8 if (_dataSource is DataView || _dataSource is DataSet || _dataSource is DataTable)
9 {
10 if (_dataSource is DataView)
11 {
12 _dataView = (DataView)_dataSource;
13 }
14 else if (_dataSource is DataSet)
15 {
16 _dataView = ((DataSet)_dataSource).Tables[0].DefaultView;
17 }
18 else // DataTable
19 {
20 _dataView = ((DataTable)_dataSource).DefaultView;
21 }
22
23 this.DataBindToDataView(_dataView);
24 }
25 else if (_dataSource is IEnumerable)
26 {
27 this.DataBindToEnumerable((IEnumerable)_dataSource);
28 }
29 else
30 {
31 throw new Exception("Cannot bind to data source of type " + _dataSource.GetType().ToString());
32 }
33 }
34
35 base.DataBind();
36
37 //_dataBound = true;
38 }
39
40 private void DataBindToDataView(DataView oDataView)
41 {
42 this.LoadGrid(oDataView);
43 // Get some info about the dataset
44 }
45
46 private void DataBindToEnumerable(IEnumerable arList)
47 {
48 throw new NotSupportedException("该方法未被支持,后面的版本也许会支持");
49 }
50
51 private void LoadGrid(DataView oDataView)
52 {
53 DataTable oTable = oDataView.Table;
54 if (oTable == null || oTable.Rows.Count == 0) return;
55 BuildFromDataTable(oTable);
56 }
57
58
59 private void BuildFromDataTable(DataTable table)
60 {
61 if (this._measurefieldname == null || this._measurefieldname == "")
62 {
63 throw new ArgumentNullException("MeasureFieldName", "请设置数据列");
64 }
65 if ((this._onColumnsAxesFieldName == null || this._onColumnsAxesFieldName == "")
66 && (this._onRowAxesFieldName == null || this._onRowAxesFieldName == "")
67 )
68 {
69 throw new ArgumentNullException("OnColumnsAxesFieldName OR OnRowAxesFieldName", "横轴和纵轴不能同时为空");
70
71 }
72 else
73 {
74 构建横竖轴#region 构建横竖轴
75 string[] cols = (this.OnColumnsAxesFieldName != null && this.OnColumnsAxesFieldName != "") ? this.OnColumnsAxesFieldName.Split(','): null;
76 string[] rows = (this.OnRowAxesFieldName != null && this.OnRowAxesFieldName != "") ? this.OnRowAxesFieldName.Split(',') : null;
77 string[] colsvalue =(this.OnColumnsAxesValueFieldName != null && this.OnColumnsAxesValueFieldName != "") ? this.OnColumnsAxesValueFieldName.Split(','): null;
78 string[] rowsvalue = (this.OnRowAxesValueFieldName != null && this.OnRowAxesValueFieldName != "") ? this.OnRowAxesValueFieldName.Split(',') : null;
79 if (colsvalue != null && colsvalue.Length != cols.Length)
80 {
81 throw new ArgumentNullException("OnColumnsAxesFieldName , OnColumnsAxesValueFieldName", "轴名称列和轴值列必须一一对应");
82 }
83 if (rowsvalue != null && rowsvalue.Length != rows.Length)
84 {
85 throw new ArgumentNullException("OnRowAxesFieldName , OnRowAxesValueFieldName", "轴名称列和轴值列必须一一对应");
86 }
87
88 // 声明需要用到的变量
89 PositionCollection pc;
90 Position ps;
91 MemberCollection mc;
92 Member mb;
93 int index ;
94 int valueindex =0;
95 DataRow[] arrdr;
96 string col;
97 string row;
98 string colvalue;
99 string rowvalue;
100 if (cols != null) //如果设置了维度列在竖轴上,则构建竖轴
101 {
102 pc = new PositionCollection();
103 for (int k = 0; k < cols.Length; k++ )
104 {
105 col = cols[k];
106 if (colsvalue != null)
107 {
108 colvalue = colsvalue[k];
109 valueindex = table.Columns[colvalue].Ordinal;
110 }
111 index = table.Columns[col].Ordinal;
112 ps = new Position();
113 ps.Name = col;
114 mc = new MemberCollection();
115 arrdr = table.Select("", col + " asc "); //过滤相同的维度信息做准备
116 for (int i = 0; i < arrdr.Length; i++)
117 {
118 if (arrdr[i][index].ToString() == "$#NULL#$") continue; // 过滤空的维度值
119 if (i == 0 || arrdr[i][index].ToString() != arrdr[i - 1][index].ToString())
120 {
121 mb = new Member();
122 mb.Caption = (arrdr[i][index] != null && arrdr[i][index] != System.DBNull.Value) ? arrdr[i][index].ToString() : "";
123 if (colsvalue != null)
124 {
125 mb.Value = (arrdr[i][valueindex] != null && arrdr[i][valueindex] != System.DBNull.Value) ? arrdr[i][valueindex].ToString() : "";
126 }
127 ps.Members.Add(mb);
128 }
129 }
130 if (this.ShowColumnsSum) //是否在竖轴上显示合计列
131 {
132 mb = new Member();
133 mb.Caption = this.SumText;
134 mb.IsSumTotal = true;
135 mb.Value = "$SUM$";
136 ps.Members.Add(mb);
137 }
138 this.ColumnsAxes.Add(ps);
139 }
140
141
142 }
143 if (rows != null) //构建横轴,同上
144 {
145
146 for (int k = 0; k < rows.Length; k++)
147 {
148 row = rows[k];
149 if (rowsvalue != null)//
150 {
151 rowvalue = rowsvalue[k];
152 valueindex = table.Columns[rowvalue].Ordinal;
153 }
154 index = table.Columns[row].Ordinal;
155
156 ps = new Position();
157 ps.Name = row;
158 mc = new MemberCollection();
159 arrdr = table.Select("", row+" asc ");
160 for (int i = 0; i < arrdr.Length ; i++)
161 {
162 if (arrdr[i][index].ToString() == "$#NULL#$") continue;
163
164 if (i == 0 || arrdr[i][index].ToString() != arrdr[i - 1][index].ToString())
165 {
166 mb = new Member();
167 mb.Caption = (arrdr[i][index] != null && arrdr[i][index] != System.DBNull.Value) ? arrdr[i][index].ToString() : "";
168 if (rowsvalue != null)
169 {
170 mb.Value = (arrdr[i][valueindex] != null && arrdr[i][valueindex] != System.DBNull.Value) ? arrdr[i][valueindex].ToString() : "";
171 }
172 ps.Members.Add(mb);
173 }
174 }
175 if (this.ShowRowsSum)
176 {
177 mb = new Member();
178 mb.Caption = this.SumText;
179 mb.IsSumTotal = true;
180 mb.Value = "$SUM$";
181 ps.Members.Add(mb);
182 }
183 this.RowAxes.Add(ps);
184 }
185
186 }
187 #endregion
188
189 获取数据#region 获取数据
190 //开始获取数据拉
191 int totalcols = 1;
192 foreach (Position cps in this.ColumnsAxes)
193 {
194 totalcols *= cps.Members.Count;
195 }
196 this.dataCells.BreakIndex = totalcols ;
197 int totalrows = 1;
198 foreach (Position rps in this.RowAxes)
199 {
200 totalrows *= rps.Members.Count;
201 }
202
203 int colscount = this.ColumnsAxes.Count;
204 int rowscount = this.RowAxes.Count;
205 string codition = "";
206 string fun = "";
207
208 int rowmindex = 0 ;
209 int colmindex = 0;
210 Cell cell;
211 for( int i =0 ;i<totalrows ; i++)
212 {
213 for (int j = 0; j < totalcols; j++)
214 {
215 codition = "";
216 fun = this._cellclientfunction;
217 for (int m = rowscount - 1; m >= 0; m--)
218 {
219
220 rowmindex = RowMemberIndex(m, i);
221 if (!this.RowAxes[m].Members[rowmindex].IsSumTotal)
222 {
223 if (codition != "") codition += " and ";
224 codition += this.RowAxes[m].Name + "='" + this.RowAxes[m].Members[rowmindex].Caption + "'";
225 }
226 if (fun != "")
227 {
228 fun = fun.Replace("{" + this.RowAxes[m].Name + "}", "'"+this.RowAxes[m].Members[rowmindex].Value.Replace("'","")+"'");
229 }
230 }
231 for (int n = colscount - 1; n >= 0; n--)
232 {
233 colmindex = ColMemberIndex(n, j);
234 if (!this.ColumnsAxes[n].Members[colmindex].IsSumTotal)
235 {
236 if (codition != "") codition += " and ";
237 codition += this.ColumnsAxes[n].Name + "='" + this.ColumnsAxes[n].Members[colmindex].Caption + "'";
238 }
239 if (fun != "")
240 {
241 fun = fun.Replace("{" + this.ColumnsAxes[n].Name + "}", "'" + this.ColumnsAxes[n].Members[colmindex].Value.Replace("'", "") + "'");
242 }
243 }
244 object o =table.Compute("sum(" + this.MeasureFieldName + ")", codition);
245 cell = new Cell();
246 if (this._cellclientfunction != null && this._cellclientfunction != "")
247 cell.ClientClickFunction = fun;
248
249 if (_formartstring != null && _formartstring != "")
250 cell.FormatString = _formartstring;
251
252 cell.Value = Convert.ToDecimal(o!=null && o !=System.DBNull.Value ?o:0);
253 this.dataCells.Add(cell);
254 fun = "";
255 }
256 }
257 #endregion
258 }
259 }
260 #endregion
2 private DataView _dataView;
3 public override void DataBind()
4 {
5 // Load the data 其中dataSource是已经绑定的数据源
6 if (_dataSource != null)
7 {
8 if (_dataSource is DataView || _dataSource is DataSet || _dataSource is DataTable)
9 {
10 if (_dataSource is DataView)
11 {
12 _dataView = (DataView)_dataSource;
13 }
14 else if (_dataSource is DataSet)
15 {
16 _dataView = ((DataSet)_dataSource).Tables[0].DefaultView;
17 }
18 else // DataTable
19 {
20 _dataView = ((DataTable)_dataSource).DefaultView;
21 }
22
23 this.DataBindToDataView(_dataView);
24 }
25 else if (_dataSource is IEnumerable)
26 {
27 this.DataBindToEnumerable((IEnumerable)_dataSource);
28 }
29 else
30 {
31 throw new Exception("Cannot bind to data source of type " + _dataSource.GetType().ToString());
32 }
33 }
34
35 base.DataBind();
36
37 //_dataBound = true;
38 }
39
40 private void DataBindToDataView(DataView oDataView)
41 {
42 this.LoadGrid(oDataView);
43 // Get some info about the dataset
44 }
45
46 private void DataBindToEnumerable(IEnumerable arList)
47 {
48 throw new NotSupportedException("该方法未被支持,后面的版本也许会支持");
49 }
50
51 private void LoadGrid(DataView oDataView)
52 {
53 DataTable oTable = oDataView.Table;
54 if (oTable == null || oTable.Rows.Count == 0) return;
55 BuildFromDataTable(oTable);
56 }
57
58
59 private void BuildFromDataTable(DataTable table)
60 {
61 if (this._measurefieldname == null || this._measurefieldname == "")
62 {
63 throw new ArgumentNullException("MeasureFieldName", "请设置数据列");
64 }
65 if ((this._onColumnsAxesFieldName == null || this._onColumnsAxesFieldName == "")
66 && (this._onRowAxesFieldName == null || this._onRowAxesFieldName == "")
67 )
68 {
69 throw new ArgumentNullException("OnColumnsAxesFieldName OR OnRowAxesFieldName", "横轴和纵轴不能同时为空");
70
71 }
72 else
73 {
74 构建横竖轴#region 构建横竖轴
75 string[] cols = (this.OnColumnsAxesFieldName != null && this.OnColumnsAxesFieldName != "") ? this.OnColumnsAxesFieldName.Split(','): null;
76 string[] rows = (this.OnRowAxesFieldName != null && this.OnRowAxesFieldName != "") ? this.OnRowAxesFieldName.Split(',') : null;
77 string[] colsvalue =(this.OnColumnsAxesValueFieldName != null && this.OnColumnsAxesValueFieldName != "") ? this.OnColumnsAxesValueFieldName.Split(','): null;
78 string[] rowsvalue = (this.OnRowAxesValueFieldName != null && this.OnRowAxesValueFieldName != "") ? this.OnRowAxesValueFieldName.Split(',') : null;
79 if (colsvalue != null && colsvalue.Length != cols.Length)
80 {
81 throw new ArgumentNullException("OnColumnsAxesFieldName , OnColumnsAxesValueFieldName", "轴名称列和轴值列必须一一对应");
82 }
83 if (rowsvalue != null && rowsvalue.Length != rows.Length)
84 {
85 throw new ArgumentNullException("OnRowAxesFieldName , OnRowAxesValueFieldName", "轴名称列和轴值列必须一一对应");
86 }
87
88 // 声明需要用到的变量
89 PositionCollection pc;
90 Position ps;
91 MemberCollection mc;
92 Member mb;
93 int index ;
94 int valueindex =0;
95 DataRow[] arrdr;
96 string col;
97 string row;
98 string colvalue;
99 string rowvalue;
100 if (cols != null) //如果设置了维度列在竖轴上,则构建竖轴
101 {
102 pc = new PositionCollection();
103 for (int k = 0; k < cols.Length; k++ )
104 {
105 col = cols[k];
106 if (colsvalue != null)
107 {
108 colvalue = colsvalue[k];
109 valueindex = table.Columns[colvalue].Ordinal;
110 }
111 index = table.Columns[col].Ordinal;
112 ps = new Position();
113 ps.Name = col;
114 mc = new MemberCollection();
115 arrdr = table.Select("", col + " asc "); //过滤相同的维度信息做准备
116 for (int i = 0; i < arrdr.Length; i++)
117 {
118 if (arrdr[i][index].ToString() == "$#NULL#$") continue; // 过滤空的维度值
119 if (i == 0 || arrdr[i][index].ToString() != arrdr[i - 1][index].ToString())
120 {
121 mb = new Member();
122 mb.Caption = (arrdr[i][index] != null && arrdr[i][index] != System.DBNull.Value) ? arrdr[i][index].ToString() : "";
123 if (colsvalue != null)
124 {
125 mb.Value = (arrdr[i][valueindex] != null && arrdr[i][valueindex] != System.DBNull.Value) ? arrdr[i][valueindex].ToString() : "";
126 }
127 ps.Members.Add(mb);
128 }
129 }
130 if (this.ShowColumnsSum) //是否在竖轴上显示合计列
131 {
132 mb = new Member();
133 mb.Caption = this.SumText;
134 mb.IsSumTotal = true;
135 mb.Value = "$SUM$";
136 ps.Members.Add(mb);
137 }
138 this.ColumnsAxes.Add(ps);
139 }
140
141
142 }
143 if (rows != null) //构建横轴,同上
144 {
145
146 for (int k = 0; k < rows.Length; k++)
147 {
148 row = rows[k];
149 if (rowsvalue != null)//
150 {
151 rowvalue = rowsvalue[k];
152 valueindex = table.Columns[rowvalue].Ordinal;
153 }
154 index = table.Columns[row].Ordinal;
155
156 ps = new Position();
157 ps.Name = row;
158 mc = new MemberCollection();
159 arrdr = table.Select("", row+" asc ");
160 for (int i = 0; i < arrdr.Length ; i++)
161 {
162 if (arrdr[i][index].ToString() == "$#NULL#$") continue;
163
164 if (i == 0 || arrdr[i][index].ToString() != arrdr[i - 1][index].ToString())
165 {
166 mb = new Member();
167 mb.Caption = (arrdr[i][index] != null && arrdr[i][index] != System.DBNull.Value) ? arrdr[i][index].ToString() : "";
168 if (rowsvalue != null)
169 {
170 mb.Value = (arrdr[i][valueindex] != null && arrdr[i][valueindex] != System.DBNull.Value) ? arrdr[i][valueindex].ToString() : "";
171 }
172 ps.Members.Add(mb);
173 }
174 }
175 if (this.ShowRowsSum)
176 {
177 mb = new Member();
178 mb.Caption = this.SumText;
179 mb.IsSumTotal = true;
180 mb.Value = "$SUM$";
181 ps.Members.Add(mb);
182 }
183 this.RowAxes.Add(ps);
184 }
185
186 }
187 #endregion
188
189 获取数据#region 获取数据
190 //开始获取数据拉
191 int totalcols = 1;
192 foreach (Position cps in this.ColumnsAxes)
193 {
194 totalcols *= cps.Members.Count;
195 }
196 this.dataCells.BreakIndex = totalcols ;
197 int totalrows = 1;
198 foreach (Position rps in this.RowAxes)
199 {
200 totalrows *= rps.Members.Count;
201 }
202
203 int colscount = this.ColumnsAxes.Count;
204 int rowscount = this.RowAxes.Count;
205 string codition = "";
206 string fun = "";
207
208 int rowmindex = 0 ;
209 int colmindex = 0;
210 Cell cell;
211 for( int i =0 ;i<totalrows ; i++)
212 {
213 for (int j = 0; j < totalcols; j++)
214 {
215 codition = "";
216 fun = this._cellclientfunction;
217 for (int m = rowscount - 1; m >= 0; m--)
218 {
219
220 rowmindex = RowMemberIndex(m, i);
221 if (!this.RowAxes[m].Members[rowmindex].IsSumTotal)
222 {
223 if (codition != "") codition += " and ";
224 codition += this.RowAxes[m].Name + "='" + this.RowAxes[m].Members[rowmindex].Caption + "'";
225 }
226 if (fun != "")
227 {
228 fun = fun.Replace("{" + this.RowAxes[m].Name + "}", "'"+this.RowAxes[m].Members[rowmindex].Value.Replace("'","")+"'");
229 }
230 }
231 for (int n = colscount - 1; n >= 0; n--)
232 {
233 colmindex = ColMemberIndex(n, j);
234 if (!this.ColumnsAxes[n].Members[colmindex].IsSumTotal)
235 {
236 if (codition != "") codition += " and ";
237 codition += this.ColumnsAxes[n].Name + "='" + this.ColumnsAxes[n].Members[colmindex].Caption + "'";
238 }
239 if (fun != "")
240 {
241 fun = fun.Replace("{" + this.ColumnsAxes[n].Name + "}", "'" + this.ColumnsAxes[n].Members[colmindex].Value.Replace("'", "") + "'");
242 }
243 }
244 object o =table.Compute("sum(" + this.MeasureFieldName + ")", codition);
245 cell = new Cell();
246 if (this._cellclientfunction != null && this._cellclientfunction != "")
247 cell.ClientClickFunction = fun;
248
249 if (_formartstring != null && _formartstring != "")
250 cell.FormatString = _formartstring;
251
252 cell.Value = Convert.ToDecimal(o!=null && o !=System.DBNull.Value ?o:0);
253 this.dataCells.Add(cell);
254 fun = "";
255 }
256 }
257 #endregion
258 }
259 }
260 #endregion
绘制表格的部分
绘制表格#region 绘制表格
protected override void RenderContents(System.Web.UI.HtmlTextWriter output)
{
//base.RenderContents(writer);
if (this.dataCells == null || this.dataCells.Count == 0) return;
int totalcols = 1;
foreach (Position ps in this.ColumnsAxes)
{
totalcols *= ps.Members.Count;
}
int totalrows = 1;
foreach (Position ps in this.RowAxes)
{
totalrows *= ps.Members.Count;
}
//开始绘制表格
output.AddAttribute("ID", this.UniqueID);
//output.AddAttribute("border", "0");
output.AddAttribute("CellSpacing", this._cellspacing.ToString());
output.AddAttribute("CellPadding", this._cellpadding.ToString());
output.AddAttribute("Width", this._width.ToString());
output.AddAttribute("Height", this._height.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
output.RenderBeginTag(HtmlTextWriterTag.Table);
//绘制第一个行
output.RenderBeginTag(HtmlTextWriterTag.Tr);
//绘制第一个单元格
if (this.RowAxes.Count != 0 && this.ColumnsAxes.Count != 0)
{
output.AddAttribute("Align", "center");
output.AddAttribute("ColSpan", this.RowAxes.Count.ToString());
output.AddAttribute("RowSpan", this.ColumnsAxes.Count.ToString());
if (this.CrossHeadClass != null && this.CrossHeadClass!="")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.CrossHeadClass);
}
if (!this.CrossHeadBgColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.CrossHeadBgColor));
}
this.RenderStyle(TDClass.TdLTBR, output); //表格样式
output.RenderBeginTag(HtmlTextWriterTag.Td);
output.Write(" ");
output.RenderEndTag();
}
int colscount;
//绘制表头
for (int i = 0; i < this.ColumnsAxes.Count; i++)
{
if (i > 0)
{
output.RenderBeginTag(HtmlTextWriterTag.Tr);
}
colscount = ColMemberCount(i);
for (int m = 0; m < colscount; m++)
{
for (int j = 0; j < this.ColumnsAxes[i].Members.Count; j++)
{
if (i == 0)
{
if(this.RowAxes.Count ==0 && j==0 )
this.RenderStyle(TDClass.TdLTBR, output);
else
this.RenderStyle(TDClass.TdTBR, output);
}
else
{
if (this.RowAxes.Count == 0 && j == 0 && m==0)
this.RenderStyle(TDClass.TdLBR, output);
else
this.RenderStyle(TDClass.TdBR, output);
}
output.AddAttribute("Align", "center");
if (this.AxisClass != null && this.AxisClass != "")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.AxisClass);
}
if (!this.AxisColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.AxisColor));
}
if (!this.AxisTextColor.IsEmpty)
{
output.AddStyleAttribute("Color", ColorTranslator.ToHtml(this.AxisTextColor));
}
output.AddAttribute("ColSpan", ColPostionClildCount(i).ToString());
output.RenderBeginTag(HtmlTextWriterTag.Td);
if (this.ColumnsAxes[i].Members[j].Caption != null && this.ColumnsAxes[i].Members[j].Caption !="")
output.Write(this.ColumnsAxes[i].Members[j].Caption);
else
output.Write(" ");
output.RenderEndTag();
}
}
output.RenderEndTag();
}
//表头绘制完毕
for (int i = 0; i < totalrows; i++)
{
output.RenderBeginTag(HtmlTextWriterTag.Tr);
//绘制竖轴
for (int j = 0; j < this.RowAxes.Count; j++)
{
if (this.IsRenderTD(j, i))
{
if (j == 0)
{
if(this.ColumnsAxes.Count ==0 && i==0)
this.RenderStyle(TDClass.TdLTBR, output);
else
this.RenderStyle(TDClass.TdLBR, output);
}
else
{
if (this.ColumnsAxes.Count == 0 && i == 0)
this.RenderStyle(TDClass.TdTBR, output);
else
this.RenderStyle(TDClass.TdBR, output);
}
output.AddAttribute("Align", "center");
if (this.AxisClass != null && this.AxisClass != "")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.AxisClass);
}
if (!this.AxisColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.AxisColor));
}
if (!this.AxisTextColor.IsEmpty)
{
output.AddStyleAttribute("Color", ColorTranslator.ToHtml(this.AxisTextColor));
}
output.AddAttribute("Rowspan", RowPostionClildCount(j).ToString());
output.RenderBeginTag(HtmlTextWriterTag.Td);
int m = RowMemberIndex(j, i);
if (this.RowAxes[j].Members[m].Caption != null && this.RowAxes[j].Members[m].Caption !="")
output.Write(this.RowAxes[j].Members[m].Caption);
else
output.Write(" ");
output.RenderEndTag();
}
}
// 绘制数据单元格
for (int j = 0; j < totalcols; j++)
{
if (i == 0 && j==0 && this.ColumnsAxes.Count ==0)
{
this.RenderStyle(TDClass.TdTBR, output);
}
else if (i == 0 && j == 0 && this.RowAxes.Count == 0)
{
this.RenderStyle(TDClass.TdLBR, output);
}
else
{
this.RenderStyle(TDClass.TdBR, output);
}
if (this._cellclientfunction != null && this._cellclientfunction != "")
{
output.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
output.AddAttribute(HtmlTextWriterAttribute.Onclick, dataCells[i, j].ClientClickFunction);
}
if (this.CellCssClass !=null && this.CellCssClass !="")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.CellCssClass);
}
if (!this.CellBgColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.CellBgColor));
}
if (!this.CellTextColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.Color, ColorTranslator.ToHtml(this.CellTextColor));
}
if (!this.CellHeight.IsEmpty)
{
output.AddAttribute(HtmlTextWriterAttribute.Height, this.CellHeight.ToString());
}
if (!this.CellWidth.IsEmpty)
{
output.AddAttribute(HtmlTextWriterAttribute.Width, this.CellWidth.ToString());
}
output.RenderBeginTag(HtmlTextWriterTag.Td);
output.Write(dataCells[i, j].Text);
output.RenderEndTag();
}
output.RenderEndTag();
}
output.RenderEndTag();
}
#endregion
protected override void RenderContents(System.Web.UI.HtmlTextWriter output)
{
//base.RenderContents(writer);
if (this.dataCells == null || this.dataCells.Count == 0) return;
int totalcols = 1;
foreach (Position ps in this.ColumnsAxes)
{
totalcols *= ps.Members.Count;
}
int totalrows = 1;
foreach (Position ps in this.RowAxes)
{
totalrows *= ps.Members.Count;
}
//开始绘制表格
output.AddAttribute("ID", this.UniqueID);
//output.AddAttribute("border", "0");
output.AddAttribute("CellSpacing", this._cellspacing.ToString());
output.AddAttribute("CellPadding", this._cellpadding.ToString());
output.AddAttribute("Width", this._width.ToString());
output.AddAttribute("Height", this._height.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
output.RenderBeginTag(HtmlTextWriterTag.Table);
//绘制第一个行
output.RenderBeginTag(HtmlTextWriterTag.Tr);
//绘制第一个单元格
if (this.RowAxes.Count != 0 && this.ColumnsAxes.Count != 0)
{
output.AddAttribute("Align", "center");
output.AddAttribute("ColSpan", this.RowAxes.Count.ToString());
output.AddAttribute("RowSpan", this.ColumnsAxes.Count.ToString());
if (this.CrossHeadClass != null && this.CrossHeadClass!="")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.CrossHeadClass);
}
if (!this.CrossHeadBgColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.CrossHeadBgColor));
}
this.RenderStyle(TDClass.TdLTBR, output); //表格样式
output.RenderBeginTag(HtmlTextWriterTag.Td);
output.Write(" ");
output.RenderEndTag();
}
int colscount;
//绘制表头
for (int i = 0; i < this.ColumnsAxes.Count; i++)
{
if (i > 0)
{
output.RenderBeginTag(HtmlTextWriterTag.Tr);
}
colscount = ColMemberCount(i);
for (int m = 0; m < colscount; m++)
{
for (int j = 0; j < this.ColumnsAxes[i].Members.Count; j++)
{
if (i == 0)
{
if(this.RowAxes.Count ==0 && j==0 )
this.RenderStyle(TDClass.TdLTBR, output);
else
this.RenderStyle(TDClass.TdTBR, output);
}
else
{
if (this.RowAxes.Count == 0 && j == 0 && m==0)
this.RenderStyle(TDClass.TdLBR, output);
else
this.RenderStyle(TDClass.TdBR, output);
}
output.AddAttribute("Align", "center");
if (this.AxisClass != null && this.AxisClass != "")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.AxisClass);
}
if (!this.AxisColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.AxisColor));
}
if (!this.AxisTextColor.IsEmpty)
{
output.AddStyleAttribute("Color", ColorTranslator.ToHtml(this.AxisTextColor));
}
output.AddAttribute("ColSpan", ColPostionClildCount(i).ToString());
output.RenderBeginTag(HtmlTextWriterTag.Td);
if (this.ColumnsAxes[i].Members[j].Caption != null && this.ColumnsAxes[i].Members[j].Caption !="")
output.Write(this.ColumnsAxes[i].Members[j].Caption);
else
output.Write(" ");
output.RenderEndTag();
}
}
output.RenderEndTag();
}
//表头绘制完毕
for (int i = 0; i < totalrows; i++)
{
output.RenderBeginTag(HtmlTextWriterTag.Tr);
//绘制竖轴
for (int j = 0; j < this.RowAxes.Count; j++)
{
if (this.IsRenderTD(j, i))
{
if (j == 0)
{
if(this.ColumnsAxes.Count ==0 && i==0)
this.RenderStyle(TDClass.TdLTBR, output);
else
this.RenderStyle(TDClass.TdLBR, output);
}
else
{
if (this.ColumnsAxes.Count == 0 && i == 0)
this.RenderStyle(TDClass.TdTBR, output);
else
this.RenderStyle(TDClass.TdBR, output);
}
output.AddAttribute("Align", "center");
if (this.AxisClass != null && this.AxisClass != "")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.AxisClass);
}
if (!this.AxisColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.AxisColor));
}
if (!this.AxisTextColor.IsEmpty)
{
output.AddStyleAttribute("Color", ColorTranslator.ToHtml(this.AxisTextColor));
}
output.AddAttribute("Rowspan", RowPostionClildCount(j).ToString());
output.RenderBeginTag(HtmlTextWriterTag.Td);
int m = RowMemberIndex(j, i);
if (this.RowAxes[j].Members[m].Caption != null && this.RowAxes[j].Members[m].Caption !="")
output.Write(this.RowAxes[j].Members[m].Caption);
else
output.Write(" ");
output.RenderEndTag();
}
}
// 绘制数据单元格
for (int j = 0; j < totalcols; j++)
{
if (i == 0 && j==0 && this.ColumnsAxes.Count ==0)
{
this.RenderStyle(TDClass.TdTBR, output);
}
else if (i == 0 && j == 0 && this.RowAxes.Count == 0)
{
this.RenderStyle(TDClass.TdLBR, output);
}
else
{
this.RenderStyle(TDClass.TdBR, output);
}
if (this._cellclientfunction != null && this._cellclientfunction != "")
{
output.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
output.AddAttribute(HtmlTextWriterAttribute.Onclick, dataCells[i, j].ClientClickFunction);
}
if (this.CellCssClass !=null && this.CellCssClass !="")
{
output.AddAttribute(HtmlTextWriterAttribute.Class, this.CellCssClass);
}
if (!this.CellBgColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(this.CellBgColor));
}
if (!this.CellTextColor.IsEmpty)
{
output.AddStyleAttribute(HtmlTextWriterStyle.Color, ColorTranslator.ToHtml(this.CellTextColor));
}
if (!this.CellHeight.IsEmpty)
{
output.AddAttribute(HtmlTextWriterAttribute.Height, this.CellHeight.ToString());
}
if (!this.CellWidth.IsEmpty)
{
output.AddAttribute(HtmlTextWriterAttribute.Width, this.CellWidth.ToString());
}
output.RenderBeginTag(HtmlTextWriterTag.Td);
output.Write(dataCells[i, j].Text);
output.RenderEndTag();
}
output.RenderEndTag();
}
output.RenderEndTag();
}
#endregion
其他一些辅助函数
私有辅助函数#region 私有辅助函数
private int RowMemberIndex(int pindex, int cindex)
{
int total = 1;
for (int i = pindex + 1; i < this.RowAxes.Count; i++)
{
total *= this.RowAxes[i].Members.Count;
}
int mcount = this.RowAxes[pindex].Members.Count;
return ((int)(cindex / total)) % (mcount);
//int m = this.RowAxes[pindex].Members.Count;
//return (cindex % m);
}
private int ColMemberIndex(int pindex, int cindex)
{
int total = 1;
for (int i = pindex + 1; i < this.ColumnsAxes.Count; i++)
{
total *= this.ColumnsAxes[i].Members.Count;
}
int mcount = this.ColumnsAxes[pindex].Members.Count;
return ((int)(cindex / total)) % (mcount);
//int m = this.ColumnsAxes[pindex].Members.Count;
//return (cindex % m);
}
private int RowPostionClildCount(int pindex)
{
int total = 1;
for (int i = pindex+1; i < this.RowAxes.Count; i++)
{
total *= this.RowAxes[i].Members.Count;
}
return total;
}
private int ColPostionClildCount(int pindex)
{
int total = 1;
for (int i = pindex+1; i < this.ColumnsAxes.Count; i++)
{
total *= this.ColumnsAxes[i].Members.Count;
}
return total;
}
private int ColMemberCount(int pindex)
{
int total = 1;
for (int i =0; i < pindex; i++)
{
total *= this.ColumnsAxes[i].Members.Count;
}
return total;
}
private bool IsRenderTD(int pindex,int cindex)
{
int total = 1;
for (int i = pindex+1; i < this.RowAxes.Count; i++)
{
total *= this.RowAxes[i].Members.Count;
}
return (cindex % total) == 0;
}
#endregion
添加单元格边框样式#region 添加单元格边框样式
/**//// <summary>
/// 添加单元格边框样式
/// </summary>
/// <param name="tdc"></param>
/// <param name="output"></param>
protected virtual void RenderStyle(TDClass tdc, HtmlTextWriter output)
{
int tdclasscode = (int)tdc;
if ((tdclasscode & 1) != 0) //上
{
output.AddStyleAttribute("border-top", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-top", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
if ((tdclasscode & 2) != 0)//下
{
output.AddStyleAttribute("border-bottom", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-bottom", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
if ((tdclasscode & 4) != 0)//左
{
output.AddStyleAttribute("border-left", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-left", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
if ((tdclasscode & 8) != 0)//右
{
output.AddStyleAttribute("border-right", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-right", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
}
#endregion
private int RowMemberIndex(int pindex, int cindex)
{
int total = 1;
for (int i = pindex + 1; i < this.RowAxes.Count; i++)
{
total *= this.RowAxes[i].Members.Count;
}
int mcount = this.RowAxes[pindex].Members.Count;
return ((int)(cindex / total)) % (mcount);
//int m = this.RowAxes[pindex].Members.Count;
//return (cindex % m);
}
private int ColMemberIndex(int pindex, int cindex)
{
int total = 1;
for (int i = pindex + 1; i < this.ColumnsAxes.Count; i++)
{
total *= this.ColumnsAxes[i].Members.Count;
}
int mcount = this.ColumnsAxes[pindex].Members.Count;
return ((int)(cindex / total)) % (mcount);
//int m = this.ColumnsAxes[pindex].Members.Count;
//return (cindex % m);
}
private int RowPostionClildCount(int pindex)
{
int total = 1;
for (int i = pindex+1; i < this.RowAxes.Count; i++)
{
total *= this.RowAxes[i].Members.Count;
}
return total;
}
private int ColPostionClildCount(int pindex)
{
int total = 1;
for (int i = pindex+1; i < this.ColumnsAxes.Count; i++)
{
total *= this.ColumnsAxes[i].Members.Count;
}
return total;
}
private int ColMemberCount(int pindex)
{
int total = 1;
for (int i =0; i < pindex; i++)
{
total *= this.ColumnsAxes[i].Members.Count;
}
return total;
}
private bool IsRenderTD(int pindex,int cindex)
{
int total = 1;
for (int i = pindex+1; i < this.RowAxes.Count; i++)
{
total *= this.RowAxes[i].Members.Count;
}
return (cindex % total) == 0;
}
#endregion
添加单元格边框样式#region 添加单元格边框样式
/**//// <summary>
/// 添加单元格边框样式
/// </summary>
/// <param name="tdc"></param>
/// <param name="output"></param>
protected virtual void RenderStyle(TDClass tdc, HtmlTextWriter output)
{
int tdclasscode = (int)tdc;
if ((tdclasscode & 1) != 0) //上
{
output.AddStyleAttribute("border-top", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-top", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
if ((tdclasscode & 2) != 0)//下
{
output.AddStyleAttribute("border-bottom", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-bottom", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
if ((tdclasscode & 4) != 0)//左
{
output.AddStyleAttribute("border-left", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-left", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
if ((tdclasscode & 8) != 0)//右
{
output.AddStyleAttribute("border-right", "" + ColorTranslator.ToHtml(this._bordercolor) + " " + this._borderwidth.ToString() + " solid");
}
else
{
output.AddStyleAttribute("border-right", "" + ColorTranslator.ToHtml(this._bordercolor) + " 0px solid");
}
}
#endregion
/**//// <summary>
/// TD单元格的边框样式
/// </summary>
/// 1111分别代表,右左下上
public enum TDClass
{
TdLTBR = 15, //1111
TdTBR = 11, //1011
TdLBR = 14, //1110
TdBR = 10, //1010
}
/// TD单元格的边框样式
/// </summary>
/// 1111分别代表,右左下上
public enum TDClass
{
TdLTBR = 15, //1111
TdTBR = 11, //1011
TdLBR = 14, //1110
TdBR = 10, //1010
}
代码下载