using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
// Written by Anurag Gandhi.
// Url: http://www.gandhisoft.com
// Contact me at: soft.gandhi@gmail.com
///
/// Pivots the data
///
public class Pivot
{
private DataTable _SourceTable = new DataTable();
private IEnumerable _Source = new List();
public Pivot(DataTable SourceTable)
{
_SourceTable = SourceTable;
_Source = SourceTable.Rows.Cast();
}
///
/// Pivots the DataTable based on provided RowField, DataField, Aggregate Function and ColumnFields.//
///
/// The column name of the Source Table which you want to spread into rows
/// The column name of the Source Table which you want to spread into Data Part
/// The Aggregate function which you want to apply in case matching data found more than once
/// The List of column names which you want to spread as columns
/// A DataTable containing the Pivoted Data
public DataTable PivotData(string rowField, string dataField, AggregateFunction aggregate, params string[] columnFields)
{
DataTable dt = new DataTable();
string Separator = ".";
List rowList = _Source.Select(x => x[rowField].ToString()).Distinct().ToList();
// Gets the list of columns .(dot) separated.
var colList = _Source.Select(x =>(columnFields.Select(n => x[n]).Aggregate((a, b) => a += Separator + b.ToString())).ToString()).Distinct().OrderBy(m => m);
dt.Columns.Add(rowField);
foreach (var colName in colList)
dt.Columns.Add(colName); // Cretes the result columns.//
foreach (string rowName in rowList)
{
DataRow row = dt.NewRow();
row[rowField] = rowName;
foreach (string colName in colList)
{
string strFilter = rowField + " = '" + rowName + "'";
string[] strColValues = colName.Split(Separator.ToCharArray(), StringSplitOptions.None);
for (int i = 0; i < columnFields.Length; i++)
strFilter += " and " + columnFields[i] + " = '" + strColValues[i] + "'";
row[colName] = GetData(strFilter, dataField, aggregate);
}
dt.Rows.Add(row);
}
return dt;
}
public DataTable PivotData(string rowField, string dataField, AggregateFunction aggregate, bool showSubTotal, params string[] columnFields)
{
DataTable dt = new DataTable();
string Separator = ".";
List rowList = _Source.Select(x => x[rowField].ToString()).Distinct().ToList();
// Gets the list of columns .(dot) separated.
List colList = _Source.Select(x => columnFields.Aggregate((a, b) => x[a].ToString() + Separator + x[b].ToString())).Distinct().OrderBy(m => m).ToList();
if (showSubTotal && columnFields.Length > 1)
{
string totalField = string.Empty;
for (int i = 0; i < columnFields.Length - 1; i++)
totalField += columnFields[i] + "(Total)" + Separator;
List totalList = _Source.Select(x => totalField + x[columnFields.Last()].ToString()).Distinct().OrderBy(m => m).ToList();
colList.InsertRange(0, totalList);
}
dt.Columns.Add(rowField);
colList.ForEach(x => dt.Columns.Add(x));
foreach (string rowName in rowList)
{
DataRow row = dt.NewRow();
row[rowField] = rowName;
foreach (string colName in colList)
{
string filter = rowField + " = '" + rowName + "'";
string[] colValues = colName.Split(Separator.ToCharArray(), StringSplitOptions.None);
for (int i = 0; i < columnFields.Length; i++)
if (!colValues[i].Contains("(Total)"))
filter += " and " + columnFields[i] + " = '" + colValues[i] + "'";
row[colName] = GetData(filter, dataField, colName.Contains("(Total)") ? AggregateFunction.Sum : aggregate);
}
dt.Rows.Add(row);
}
return dt;
}
public DataTable PivotData(string DataField, AggregateFunction Aggregate, string[] RowFields, string[] ColumnFields)
{
DataTable dt = new DataTable();
string Separator = ".";
var RowList = _SourceTable.DefaultView.ToTable(true, RowFields).AsEnumerable().ToList();
for (int index = RowFields.Count() - 1; index >= 0; index--)
RowList = RowList.OrderBy(x => x.Field