出处:http://www.cnblogs.com/zhuqil/archive/2010/01/07/1640772.html
代码: /Files/zhuqil/Pivot.zip
数据透视表提供的数据三维视图效果,在Microsoft Excel能创建数据透视表,但是,它并不会总是很方便使用Excel。您可能希望在Web应用程序中创建一个数据透视报表。创建一个简单的数据透视表可能是一件非常复杂的任务。所以,我打算不但为你提供一个非常有用的工具创建简单和高级的数据透视表,而且为你移除一些笼罩他们的神秘面纱。
目标是:我们想要有能力将datatable中的二维的数据转换成三维视图。
在大多数情况下,你会从数据库的查询数据填充数据表,例如
代码
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->SELECT
SalesPeople.FullNameAS[SalesPerson]
,Products.FullNameAS[Product]
,SUM(Sales.SalesAmount)AS[SaleAmount]
,SUM(Sales.Qty)AS[Quantity]
FROM
Sales
JOIN
SalesPeopleWITH(NOLOCK)
ONSalesPeople.SalesPersonID=Sales.SalesPersonID
JOIN
ProductsWITH(NOLOCK)
ONProducts.ProductCode=Sales.ProductCode
GROUPBY
SalesPeople.FullName
,Products.FullName
该查询会产生下面的数据表:
Sales Person
|
Product
|
Quantity
|
Sale Amount
|
John
|
Pens
|
200
|
350
|
John
|
Pencils
|
400
|
500
|
John
|
Notebooks
|
100
|
300
|
John
|
Rulers
|
50
|
100
|
John
|
Calculators
|
120
|
1200
|
John
|
Back Packs
|
75
|
1500
|
Jane
|
Pens
|
225
|
393.75
|
Jane
|
Pencils
|
335
|
418.75
|
Jane
|
Notebooks
|
200
|
600
|
Jane
|
Rulers
|
75
|
150
|
Jane
|
Calculators
|
80
|
800
|
Jane
|
Back Packs
|
97
|
1940
|
Sally
|
Pens
|
202
|
353.5
|
Sally
|
Pencils
|
303
|
378.75
|
Sally
|
Notebooks
|
198
|
600
|
Sally
|
Rulers
|
98
|
594
|
Sally
|
Calculators
|
80
|
800
|
Sally
|
Back Packs
|
101
|
2020
|
Sarah
|
Pens
|
112
|
196
|
Sarah
|
Pencils
|
245
|
306.25
|
Sarah
|
Notebooks
|
198
|
594
|
Sarah
|
Rulers
|
50
|
100
|
Sarah
|
Calculators
|
66
|
660
|
Sarah
|
Back Packs
|
50
|
2020
|
正如你所看到的,这是一个二维表,它不是一个非常有用的报表。因此,我们得改变,将它变成更可读的数据表。
数据透视表有3个面。
X轴构成了在表格上方的大标题。Y轴构成表的左栏,Z轴构成了X轴和Y轴对应的值。简单的数据透视表将会对每一个x轴值都只有一个z轴列,高级的数据透视表将对于每个X轴的值会对应有多个Z轴的值。
一个非常重要的一点是,Z轴的值只能是数字。这是因为Z轴值为横轴和纵轴的总额。使用一个非数值Z轴字段将抛出一个异常。
因此,如果你注意上面的数据表,你会发现,“Sales Person”和“Product”字段可以分配到的X轴或Y轴,但不能给z轴。在“Quantity”和“Sale Amount”字段可以被分配到z轴。
Pivot 类将数据表转换成html table。然后您可以将它输出到Web窗体上。那么,这只是实现的方法。如果你愿意,你可以根据这个类的逻辑创建一个用户控件。
代码
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->#regionVariables
privateDataTable_DataTable;
privatestring_CssTopHeading;
privatestring_CssSubHeading;
privatestring_CssLeftColumn;
privatestring_CssItems;
privatestring_CssTotals;
privatestring_CssTable;
#endregionVariables
#regionConstructors
publicPivot(DataTabledataTable)
{
Init();
_DataTable=dataTable;
}
#endregionConstructors
这部分的代码是非常自我解释。 你能创建一个Pivot 对象,通过传递一个datatable作为参数。在init()方法只分配一个空字符串值给CSS变量。如果CSS的变量是一个空字符串,构造方法将使用默认的样式。每一个CSS变量都有一个相应的属性。
代码
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->privatestringFindValue(stringxAxisField,stringxAxisValue,stringyAxisField,stringyAxisValue,stringzAxisField)
{
stringzAxisValue="";
try
{
foreach(DataRowrowin_DataTable.Rows)
{
if(Convert.ToString(row[xAxisField])==xAxisValue&&Convert.ToString(row[yAxisField])==yAxisValue)
{
zAxisValue=Convert.ToString(row[zAxisField]);
break;
}
}
}
catch
{
throw;
}
returnzAxisValue;
}
在FindValue(...)方法在数据表中搜索的对应x轴和y轴值的Z轴值。xAxisField是X轴字段的列名(例如“Product”),而xAxisValue是在该列的值。该yAxisField是的Y轴字段的列名(例如“Sales Person”),并yAxisValue是在该列的值。该zAxisField是列名,在其中Z轴值,是您正在寻找地(例如“Sale Amount”)。
代码
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->privatestring[]FindValues(stringxAxisField,stringxAxisValue,stringyAxisField,stringyAxisValue,string[]zAxisFields)
{
intzAxis=zAxisFields.Length;
if(zAxis<1)
zAxis++;
string[]zAxisValues=newstring[zAxis];
//setdefaultvalues
for(inti=0;i<=zAxisValues.GetUpperBound(0);i++)
{
zAxisValues[i]="0";
}
try
{
foreach(DataRowrowin_DataTable.Rows)
{
if(Convert.ToString(row[xAxisField])==xAxisValue&&Convert.ToString(row[yAxisField])==yAxisValue)
{
for(intz=0;z<zAxis;z++)
{
zAxisValues[z]=Convert.ToString(row[zAxisFields[z]]);
}
break;
}
}
}
catch
{
throw;
}
returnzAxisValues;
}
在FindValues(...)方法类似FindValue(...)方法,然而,它会返回多个z轴的值。这是用于高级的数据透视表,对应于x轴的值,您会有多个Z轴列。
代码
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->privatevoidMainHeaderTopCellStyle(HtmlTableCellcell)
{
if(_CssTopHeading=="")
{
cell.Style.Add("font-family","tahoma");
cell.Style.Add("font-size","10pt");
cell.Style.Add("font-weight","normal");
cell.Style.Add("background-color","black");
cell.Style.Add("color","white");
cell.Style.Add("text-align","center");
}
else
cell.Attributes.Add("Class",_CssTopHeading);
}
这是CSS样式的方法之一。这在X轴上使用流行的样式(table的顶行)。如果您没有指定一个CSS类名给这个属性,该方法将使用默认的样式。 CSS类将会被应用到网页中的HTML table。
代码
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->///<summary>
///Createsanadvanced3DPivottable.
///</summary>
///<paramname="xAxisField">Themainheadingatthetopofthereport.</param>
///<paramname="yAxisField">Theheadingontheleftofthereport.</param>
///<paramname="zAxisFields">Thesubheadingatthetopofthereport.</param>
///<returns>HtmlTableControl.</returns>
publicHtmlTablePivotTable(stringxAxisField,stringyAxisField,string[]zAxisFields)
{
HtmlTabletable=newHtmlTable();
//styletable
TableStyle(table);
/*
*Thex-axisisthemainhorizontalrow.
*Thez-axisisthesubhorizontalrow.
*They-axisistheleftverticalcolumn.
*/
try
{
//getdistinctxAxisFields
ArrayListxAxis=newArrayList();
foreach(DataRowrowin_DataTable.Rows)
{
if(!xAxis.Contains(row[xAxisField]))
xAxis.Add(row[xAxisField]);
}
//getdistinctyAxisFields
ArrayListyAxis=newArrayList();
foreach(DataRowrowin_DataTable.Rows)
{
if(!yAxis.Contains(row[yAxisField]))
yAxis.Add(row[yAxisField]);
}
//createa2Darrayforthey-axis/z-axisfields
intzAxis=zAxisFields.Length;
if(zAxis<1)
zAxis=1;
string[,]matrix=newstring[(xAxis.Count*zAxis),yAxis.Count];
string[]zAxisValues=newstring[zAxis];
for(inty=0;y<yAxis.Count;y++)//loopthruy-axisfields
{
//rows
for(intx=0;x<xAxis.Count;x++)//loopthrux-axisfields
{
//maincolumns
//getthez-axisvalues
zAxisValues=FindValues(xAxisField,Convert.ToString(xAxis[x])
,yAxisField,Convert.ToString(yAxis[y]),zAxisFields);
for(intz=0;z<zAxis;z++)//loopthruz-axisfields
{
//subcolumns
matrix[(((x+1)*zAxis-zAxis)+z),y]=zAxisValues[z];
}
}
}
//calculatetotalsforthey-axis
decimal[]yTotals=newdecimal[(xAxis.Count*zAxis)];
for(intcol=0;col<(xAxis.Count*zAxis);col++)
{
yTotals[col]=0;
for(introw=0;row<yAxis.Count;row++)
{
yTotals[col]+=Convert.ToDecimal(matrix[col,row]);
}
}
//calculatetotalsforthex-axis
decimal[,]xTotals=newdecimal[zAxis,(yAxis.Count+1)];
for(inty=0;y<yAxis.Count;y++)//loopthruthey-axis
{
intzCount=0;
for(intz=0;z<(zAxis*xAxis.Count);z++)//loopthruthez-axis
{
xTotals[zCount,y]+=Convert.ToDecimal(matrix[z,y]);
if(zCount==(zAxis-1))
zCount=0;
else
zCount++;
}
}
for(intxx=0;xx<zAxis;xx++)//GrandTotal
{
for(intxy=0;xy<yAxis.Count;xy++)
{
xTotals[xx,yAxis.Count]+=xTotals[xx,xy];
}
}
//BuildHTMLTable
//Appendmainrow(x-axis)
HtmlTableRowmainRow=newHtmlTableRow();
mainRow.Cells.Add(newHtmlTableCell());
for(intx=0;x<=xAxis.Count;x++)//loopthrux-axis+1
{
HtmlTableCellcell=newHtmlTableCell();
cell.ColSpan=zAxis;
if(x<xAxis.Count)
cell.InnerText=Convert.ToString(xAxis[x]);
else
cell.InnerText="GrandTotals";
//stylecell
MainHeaderTopCellStyle(cell);
mainRow.Cells.Add(cell);
}
table.Rows.Add(mainRow);
//Appendsubrow(z-axis)
HtmlTableRowsubRow=newHtmlTableRow();
subRow.Cells.Add(newHtmlTableCell());
subRow.Cells[0].InnerText=yAxisField;
//stylecell
SubHeaderCellStyle(subRow.Cells[0]);
for(intx=0;x<=xAxis.Count;x++)//loopthrux-axis+1
{
for(intz=0;z<zAxis;z++)
{
HtmlTableCellcell=newHtmlTableCell();
cell.InnerText=zAxisFields[z];
//stylecell
SubHeaderCellStyle(cell);
subRow.Cells.Add(cell);
}
}
table.Rows.Add(subRow);
//Appendtableitemsfrommatrix
for(inty=0;y<yAxis.Count;y++)//loopthruy-axis
{
HtmlTableRowitemRow=newHtmlTableRow();
for(intz=0;z<=(zAxis*xAxis.Count);z++)//loopthruz-axis+1
{
HtmlTableCellcell=newHtmlTableCell();
if(z==0)
{
cell.InnerText=Convert.ToString(yAxis[y]);
//stylecell
MainHeaderLeftCellStyle(cell);
}
else
{
cell.InnerText=Convert.ToString(matrix[(z-1),y]);
//stylecell
ItemCellStyle(cell);
}
itemRow.Cells.Add(cell);
}
//appendx-axisgrandtotals
for(intz=0;z<zAxis;z++)
{
HtmlTableCellcell=newHtmlTableCell();
cell.InnerText=Convert.ToString(xTotals[z,y]);
//stylecell
TotalCellStyle(cell);
itemRow.Cells.Add(cell);
}
table.Rows.Add(itemRow);
}
//appendy-axistotals
HtmlTableRowtotalRow=newHtmlTableRow();
for(intx=0;x<=(zAxis*xAxis.Count);x++)
{
HtmlTableCellcell=newHtmlTableCell();
if(x==0)
cell.InnerText="Totals";
else
cell.InnerText=Convert.ToString(yTotals[x-1]);
//stylecell
TotalCellStyle(cell);
totalRow.Cells.Add(cell);
}
//appendx-axis/y-axistotals
for(intz=0;z<zAxis;z++)
{
HtmlTableCellcell=newHtmlTableCell();
cell.InnerText=Convert.ToString(xTotals[z,xTotals.GetUpperBound(1)]);
//stylecell
TotalCellStyle(cell);
totalRow.Cells.Add(cell);
}
table.Rows.Add(totalRow);
}
catch
{
throw;
}
returntable;
}
PivotTable(…) 方法,是所有神奇发生的地方。有两种重载方法,一个创建了一个简单的数据透视表,而其他(上面的方法)创建一个高级的数据透视表。唯一的区别在于,一个简单只有一个的z轴,而高级的,不止一个。
Pivot.zip文件中包括两个解决方案。Pivot 是一个类库解决方案是。您可以编译此解决方案和在Web应用程序中引用Pivot.dll。另一个解决方案是PivotTest,它是是一个ASP.NET应用程序。这说明如何实现Pivot类。
相关推荐
生成Excel透视表时,Spire.Xls提供了丰富的样式选项,以满足不同需求。虽然官方帮助文档可能没有提供所有样式的预览图,但开发者可以通过尝试不同的内置样式代码来找到最适合的样式。以下是一些内置透视图样式的列表...
在IT行业中,Pivot表(也称为数据透视表)是一种强大的数据分析工具,它允许用户对大量数据进行快速的汇总和分析。在ASP.NET框架下,我们可以利用多种技术来实现Pivot表的功能,以便在Web应用中展示数据的聚合和转换...
5. **第三方组件**:还有一些商业组件,如Aspose.Cells,它们提供了全面的Excel操作功能,包括图表、数据验证、透视表等,但可能需要购买许可证。 在压缩包文件"SaturnEXCEL"中,可能包含了一个实现这些功能的...
- **具有子报表的钻取报表**:实现类似Excel数据透视表的功能,允许在复杂交叉表中按不同维度进行钻取。 通过这些示例,我们可以看到ReportViewer Control的强大功能,它不仅可以生成复杂的报表,还能提供交互式的...
Free Spire.XLS for .NET 是 Spire.XLS for .NET 的免费版本,无需购买即可用于个人或...此外,它支持使用 C#、VB.NET 或 ASP.NET 在数据库和 Excel 之间进行数据传输,支持超链接和模板,支持创建和获取数据透视表。
可以使用数据透视表、汇总和计算字段来减少数据量,或者采用懒加载策略,只在需要时加载数据。 总之,ASP.NET水晶报表为开发者提供了强大的报表设计和展示工具,通过灵活的数据绑定、参数化、交互性以及各种自定义...
1. **DevExpress的ASPxPivotGrid**: 这是一个强大的数据透视表控件,提供了丰富的打印选项,包括列和行的定制、分页和样式设置。 2. **Telerik的RadGrid**: 提供了内置的打印支持,可以直接打印整个表格或者选定的...
在Asp.Net中集成水晶报表(Crystal Reports)是一个强大且灵活的方式,用于展示和管理来自数据库的数据。...通过上述步骤,你可以在Asp.net环境中充分利用水晶报表的强大功能,实现数据的高效管理和呈现。
这可能需要用到数据分析技术,如SQL查询、数据透视表或统计图表。 5. **用户界面**:系统应该具有用户友好的界面,方便管理员和学生操作。ASP.NET提供了多种Web控件,如GridView、FormView等,可以快速构建交互式的...
3. **数据透视表**:这是一个强大的分析工具,能快速汇总、比较、探索大量数据,通过拖放字段来改变分析视角。 4. **图表制作**:Excel支持多种图表类型,如柱状图、折线图、饼图等,用于可视化数据。 5. **条件...
OWC 是一组 COM 控件集合,包括电子表格、图表和数据透视表等功能。虽然最初是作为客户端技术设计的,但在服务器端使用时,其图表绘制功能变得尤为突出。 #### 二、实现技术 要在ASP.NET环境中使用OWC来绘制Excel...
关于标签"Excel",Excel提供了丰富的功能,包括公式、图表、数据透视表、宏等,使得处理和分析数据变得简单。而与ASP.NET结合使用时,可以通过COM互操作性(例如,使用Microsoft.Office.Interop.Excel命名空间)或第...
4. **动态图表**:通过使用数据透视表和数据有效性规则,可以创建动态图表,使图表随着数据源的变化自动更新。 5. **条件格式化**:可应用于数据系列,根据数值自动改变颜色,便于快速识别数据趋势和异常值。 6. *...
在本场景中,"多个DEV控件"可能包括了几个独立的数据展示区域,比如GridControl(表格控件)、ChartControl(图表控件)或者PivotGridControl(透视表控件)等。 导出到Excel的功能在DevExpress框架中通常是通过其...
它的公式和函数系统使得复杂的数据计算变得简单,而图表和数据透视表等功能则能直观地展示数据关系。在智能信息收集系统中,Excel可以作为后端数据处理的核心,负责数据的存储、计算和报表生成。 Web技术则主要负责...
交叉表(又称透视表)可以对数据进行多维度分析;自定义函数和脚本则增强了报告的逻辑处理能力。 7. **部署与呈现** 完成设计后,水晶报表可以通过ASP.NET Web应用程序或Windows Forms应用程序进行部署。在客户端...
比如在Excel中,就有一种叫做“数据透视表”的功能可以实现这一目标。在***中,我们没有内建的类似功能,需要通过编写自定义代码来实现。 在***中合并重复数据的方法有很多,常见的有:使用脚本合并,使用后端代码...
它允许开发者创建、读取、修改和转换Excel文件(.xlsx、.xls),执行复杂的公式计算,绘制图表,处理数据透视表,以及应用条件格式。Aspose.Cells还可以将Excel数据导出为PDF、HTML、CSV等多种格式,或者导入到...
它支持复杂的公式、图表、数据透视表等功能,使得数据处理变得直观且高效。在导出TreeView数据到Excel时,我们可能会遇到的一个挑战是,如何保持数据的层级关系。在Excel中,超过26行的连续单元格合并通常用于表示...
2. 原生数据透视表:只需将元素直接拖放到数据透视表(交叉表)中,然后将其显示在报表中。 3. HTML 5 图表:通过两次鼠标单击定义和显示图表系列(支持 ChartJS,NVD3 和 Plotly 库)。 4. 使用 Razor 引擎进行完全...