using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace GT
{
/// <summary>
/// 內存表透視表生成器 2020.3.10
/// 調用方法new PivotTableGenerator(dt, "dq,xz,cw","fl","sl", "dq=地區,xz=小組,cw=財務").CreatePivotTable();
/// </summary>
public class PivotTableGenerator
{
private DataTable _source;
private DataTable _result;
string[] _fields;
string _valueFileld;
string _pivotField;
private string _fieldRenameString;
/// <summary>
/// 內存表透視表生成器 構造方式
/// 調用方法new PivotTableGenerator(dt, "dq,xz,cw","fl","sl", "dq=地區,xz=小組,cw=財務").CreatePivotTable();
/// </summary>
/// <param name="source"></param>
/// <param name="fields">如</param>
/// <param name="pivotField"></param>
/// <param name="valueField"></param>
/// <param name="fieldRenameString"></param>
public PivotTableGenerator(DataTable source, string fields, string pivotField, string valueField, string fieldRenameString)
{
if (null == source || string.IsNullOrEmpty(fields) || string.IsNullOrEmpty(pivotField) || string.IsNullOrEmpty(valueField))
{
throw new Exception(" PivotTableGenerator 初始化錯誤");
}
_source = source;
_fields = fields.Split(',');
_valueFileld = valueField;
_pivotField = pivotField;
_fieldRenameString = fieldRenameString;
}
public DataTable CreatePivotTable()
{
_result = new DataTable();
//fields
DataTable dt = new DataView(_source).ToTable(true, _fields);
for (int i = 0; i < dt.Columns.Count; i++)
{
DataColumn col = new DataColumn(dt.Columns[i].ColumnName, dt.Columns[i].DataType);
_result.Columns.Add(col);
}
foreach (DataRow dataRow in dt.Rows)
{
DataRow dr = _result.NewRow();
foreach (DataColumn dataColumn in dt.Columns)
{
dr[dataColumn.ColumnName] = dataRow[dataColumn.ColumnName];
}
_result.Rows.Add(dr);
}
if (0 == _source.Rows.Count)
return _result;
//pivot
List<string> pivotColumns = new List<string>();
Type valueType = _source.Columns[_valueFileld].DataType;
dt = new DataView(_source).ToTable(true, _pivotField);
for (int i = 0; i < dt.Rows.Count; i++)
{
string pivotFieldName = dt.Rows[i][0].ToString();
DataColumn col = new DataColumn(pivotFieldName, valueType);
_result.Columns.Add(col);
pivotColumns.Add(pivotFieldName);
}
//fild data 暫時設爲無重複數據
List<string> filter0;
foreach (DataRow dataRow in _result.Rows)
{
filter0 = new List<string>();
foreach (var item in _fields)
filter0.Add(string.Format("{0} = '{1}'", item, dataRow[item].ToString()));
foreach (string pivotFieldValue in pivotColumns)
{
List<string> filter1 = new List<string>(filter0);
filter1.Add(string.Format("{0} = '{1}'", _pivotField, pivotFieldValue));
DataRow[] drSources = _source.Select(string.Join(" and ", filter1));
if (null != drSources && drSources.Length > 0)
dataRow[pivotFieldValue] = drSources[0][_valueFileld];
}
}
if (!string.IsNullOrEmpty(_fieldRenameString))
this.ChangeFiledName();
return _result;
}
/// <summary>
/// 更改內存表字段名稱,忽略大小寫
/// </summary>
private void ChangeFiledName()
{
if (!string.IsNullOrEmpty(_fieldRenameString))
{
string[] arr1 = _fieldRenameString.Split(',');
for (int i = 0; i < arr1.Length; i++)
{
arr1[i] = arr1[i].Trim();
if (arr1[i].Length < 1)
continue;
string[] arr2 = arr1[i].Split('=');
if (arr2.Length < 2)
continue;
arr2[0] = arr2[0].Trim();
arr2[1] = arr2[1].Trim();
if (arr2[0].Length < 1 || arr2[1].Length < 1)
continue;
foreach (DataColumn column in _result.Columns)
{
if (column.ColumnName.ToLower().Equals(arr2[0].ToLower()))
column.ColumnName = arr2[1];
}
}
}
}
}
}