如何使用 Interop.Excel (C#) 对数据透视表(DESC 值)进行排序
How to sort PivotTable (DESC values) with Interop.Excel (C#)
如何使用 Interop.Excel 和 C# 对数据透视表进行排序?
我完全按照我想要的方式生成了数据透视表,但在排序方面遇到了困难...
应该进行排序,对于 "Title" 和 "SubTitle",字段 "Value2" 始终在每个项目的顶部具有最高的降序值。
正在尝试通过 Range.Sort() 但没有成功。
测试方式:
用 "C4" 定义一个区域(就像我在 Excel 中手动做的那样)并在上面做 Range.Sort。但是它适用于第一个项目,但不适用于所有项目。恕我直言,因为我只将它设置为一个单元格的指向范围。下一次尝试是扩大范围,但后来我总是得到 HRESULT 异常,只给出一个内存地址(对我没用)。
屏幕截图显示了想要的排序。
public void GeneratePivot()
{
const string numberFormat = "#,##0 €;-#,##0 €";
var missing = Type.Missing;
string dataContext = @"DataContext";
#region // Create Data
var dt = new DataTable();
dt.Columns.Add(new DataColumn() { ColumnName = "Project", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "Title", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "SubTitle", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "Value1", DataType = typeof(decimal) });
dt.Columns.Add(new DataColumn() { ColumnName = "Value2", DataType = typeof(decimal) });
var row1 = dt.NewRow();
row1["Project"] = "Project1";
row1["Title"] = "Title1";
row1["SubTitle"] = "SubTitle1-1";
row1["Value1"] = 1000M;
row1["Value2"] = 40000M;
dt.Rows.Add(row1);
var row2 = dt.NewRow();
row2["Project"] = "Project2-1";
row2["Title"] = "Title2";
row2["SubTitle"] = "SubTitle2-1";
row2["Value1"] = 100M;
row2["Value2"] = 4000M;
dt.Rows.Add(row2);
var row3 = dt.NewRow();
row3["Project"] = "Project2-2";
row3["Title"] = "Title2";
row3["SubTitle"] = "SubTitle2-2";
row3["Value1"] = 220M;
row3["Value2"] = 222000M;
dt.Rows.Add(row3);
var row4 = dt.NewRow();
row4["Project"] = "Project3-1";
row4["Title"] = "Title3";
row4["SubTitle"] = "SubTitle3-1";
row4["Value1"] = 32423M;
row4["Value2"] = 430M;
dt.Rows.Add(row4);
var row5 = dt.NewRow();
row5["Project"] = "Project3-2";
row5["Title"] = "Title3";
row5["SubTitle"] = "SubTitle3-2";
row5["Value1"] = 2341M;
row5["Value2"] = 4002000M;
dt.Rows.Add(row5);
#endregion
// Create Workbook with Excel Interop
Excel.Application excelApplication = new Excel.Application();
Excel.Workbooks workbooks = excelApplication.Workbooks;
var workbook = workbooks.Add();
#region // Create DataSheet
Excel.Worksheet worksheet1 = workbook.Sheets[1];
worksheet1.Name = "DataSheet";
var colsCount = dt.Columns.Count;
var rowsCount = dt.Rows.Count;
Excel.Range range;
// Create DataArray from DataTable
object[,] dtArray = new object[rowsCount, colsCount];
for (int i = 0; i < rowsCount; i++)
{
for (int j = 0; j < colsCount; j++) { dtArray[i, j] = dt.Rows[i][j]; }
}
// Create header
range = worksheet1.Cells[1, 1];
range = range.get_Resize(1, colsCount);
range.NumberFormat = "@";
range.Font.Bold = true;
range.Value = new string[5] { "Project", "Title", "SubTitle", "Value1", "Value2" };
// Get an Excel Range of the same dimensions
range = (Excel.Range)worksheet1.Cells[2, 1];
range = range.get_Resize(rowsCount, colsCount);
// Assign the 2-d array to the Excel Range
range.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, dtArray);
range = worksheet1.UsedRange;
worksheet1.Names.Add("DataContext", range);
#endregion
#region // Create PivotSheet
Excel.Worksheet worksheet2 = workbook.Sheets.Add(After: workbook.Sheets[workbook.Sheets.Count]);
worksheet2.Name = "PivotSheet";
Excel.PivotCache pivotCache;
Excel.PivotTable pivotTable;
Excel.Range pivotData;
Excel.Range pivotDestination;
// Select a range of data for the Pivot Table.
pivotData = worksheet1.get_Range(dataContext);
// Select location of the Pivot Table.
pivotDestination = worksheet2.get_Range("A1", missing);
// create Pivot Cache and Pivot Table
pivotCache = (Excel.PivotCache)workbook.PivotCaches()
.Add(Excel.XlPivotTableSourceType.xlDatabase, pivotData);
pivotTable = (Excel.PivotTable)worksheet2.PivotTables()
.Add(PivotCache: pivotCache, TableDestination: pivotDestination, TableName: dataContext);
// Style Pivot Table
pivotTable.Format(Excel.XlPivotFormatType.xlReport2);
pivotTable.InGridDropZones = false;
pivotTable.SmallGrid = false;
pivotTable.TableStyle2 = "PivotStyleLight16";
// ROW FIELDS
Excel.PivotField rowField3 = (Excel.PivotField)pivotTable.PivotFields("SubTitle");
rowField3.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField3.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField3.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField3.LayoutCompactRow = true;
Excel.PivotField rowField2 = (Excel.PivotField)pivotTable.PivotFields("Title");
rowField2.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField2.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField2.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField2.LayoutCompactRow = true;
Excel.PivotField rowField1 = (Excel.PivotField)pivotTable.PivotFields("Project");
rowField1.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField1.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField1.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField1.LayoutCompactRow = true;
// FILTER FIELDS
Excel.PivotField pageField1 = (Excel.PivotField)pivotTable.PivotFields("Project");
pageField1.Orientation = Excel.XlPivotFieldOrientation.xlPageField;
pageField1.EnableMultiplePageItems = true;
// DATA FIELDS
int position = 1;
Excel.PivotField dataField1 = (Excel.PivotField)pivotTable.PivotFields("Value1");
dataField1.Orientation = Excel.XlPivotFieldOrientation.xlDataField;
dataField1.Function = Excel.XlConsolidationFunction.xlSum;
dataField1.NumberFormat = numberFormat;
dataField1.Position = position++;
Excel.PivotField dataField2 = (Excel.PivotField)pivotTable.PivotFields("Value2");
dataField2.Orientation = Excel.XlPivotFieldOrientation.xlDataField;
dataField2.Function = Excel.XlConsolidationFunction.xlSum;
dataField2.NumberFormat = numberFormat;
dataField2.Position = position++;
#endregion
// Close Excel
workbook.SaveAs("Interop.Excel_Pivot.xlsx");
workbook.Close();
excelApplication.Quit();
}
做到了!
var pivotLine = (Excel.PivotLine)pivotTable.PivotColumnAxis.PivotLines[2];
rowField2.AutoSortEx((int)Excel.XlSortOrder.xlDescending, "Summe von Value2", pivotLine, 1);
rowField3.AutoSortEx((int)Excel.XlSortOrder.xlDescending, "Summe von Value2", pivotLine, 1);
提示: 注意,给定的字符串 "Summe von " 是德语,在英语中将是 "Sum of " 和 Excel。 ;)
如何使用 Interop.Excel 和 C# 对数据透视表进行排序? 我完全按照我想要的方式生成了数据透视表,但在排序方面遇到了困难...
应该进行排序,对于 "Title" 和 "SubTitle",字段 "Value2" 始终在每个项目的顶部具有最高的降序值。
正在尝试通过 Range.Sort() 但没有成功。 测试方式: 用 "C4" 定义一个区域(就像我在 Excel 中手动做的那样)并在上面做 Range.Sort。但是它适用于第一个项目,但不适用于所有项目。恕我直言,因为我只将它设置为一个单元格的指向范围。下一次尝试是扩大范围,但后来我总是得到 HRESULT 异常,只给出一个内存地址(对我没用)。
屏幕截图显示了想要的排序。
public void GeneratePivot()
{
const string numberFormat = "#,##0 €;-#,##0 €";
var missing = Type.Missing;
string dataContext = @"DataContext";
#region // Create Data
var dt = new DataTable();
dt.Columns.Add(new DataColumn() { ColumnName = "Project", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "Title", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "SubTitle", DataType = typeof(string) });
dt.Columns.Add(new DataColumn() { ColumnName = "Value1", DataType = typeof(decimal) });
dt.Columns.Add(new DataColumn() { ColumnName = "Value2", DataType = typeof(decimal) });
var row1 = dt.NewRow();
row1["Project"] = "Project1";
row1["Title"] = "Title1";
row1["SubTitle"] = "SubTitle1-1";
row1["Value1"] = 1000M;
row1["Value2"] = 40000M;
dt.Rows.Add(row1);
var row2 = dt.NewRow();
row2["Project"] = "Project2-1";
row2["Title"] = "Title2";
row2["SubTitle"] = "SubTitle2-1";
row2["Value1"] = 100M;
row2["Value2"] = 4000M;
dt.Rows.Add(row2);
var row3 = dt.NewRow();
row3["Project"] = "Project2-2";
row3["Title"] = "Title2";
row3["SubTitle"] = "SubTitle2-2";
row3["Value1"] = 220M;
row3["Value2"] = 222000M;
dt.Rows.Add(row3);
var row4 = dt.NewRow();
row4["Project"] = "Project3-1";
row4["Title"] = "Title3";
row4["SubTitle"] = "SubTitle3-1";
row4["Value1"] = 32423M;
row4["Value2"] = 430M;
dt.Rows.Add(row4);
var row5 = dt.NewRow();
row5["Project"] = "Project3-2";
row5["Title"] = "Title3";
row5["SubTitle"] = "SubTitle3-2";
row5["Value1"] = 2341M;
row5["Value2"] = 4002000M;
dt.Rows.Add(row5);
#endregion
// Create Workbook with Excel Interop
Excel.Application excelApplication = new Excel.Application();
Excel.Workbooks workbooks = excelApplication.Workbooks;
var workbook = workbooks.Add();
#region // Create DataSheet
Excel.Worksheet worksheet1 = workbook.Sheets[1];
worksheet1.Name = "DataSheet";
var colsCount = dt.Columns.Count;
var rowsCount = dt.Rows.Count;
Excel.Range range;
// Create DataArray from DataTable
object[,] dtArray = new object[rowsCount, colsCount];
for (int i = 0; i < rowsCount; i++)
{
for (int j = 0; j < colsCount; j++) { dtArray[i, j] = dt.Rows[i][j]; }
}
// Create header
range = worksheet1.Cells[1, 1];
range = range.get_Resize(1, colsCount);
range.NumberFormat = "@";
range.Font.Bold = true;
range.Value = new string[5] { "Project", "Title", "SubTitle", "Value1", "Value2" };
// Get an Excel Range of the same dimensions
range = (Excel.Range)worksheet1.Cells[2, 1];
range = range.get_Resize(rowsCount, colsCount);
// Assign the 2-d array to the Excel Range
range.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, dtArray);
range = worksheet1.UsedRange;
worksheet1.Names.Add("DataContext", range);
#endregion
#region // Create PivotSheet
Excel.Worksheet worksheet2 = workbook.Sheets.Add(After: workbook.Sheets[workbook.Sheets.Count]);
worksheet2.Name = "PivotSheet";
Excel.PivotCache pivotCache;
Excel.PivotTable pivotTable;
Excel.Range pivotData;
Excel.Range pivotDestination;
// Select a range of data for the Pivot Table.
pivotData = worksheet1.get_Range(dataContext);
// Select location of the Pivot Table.
pivotDestination = worksheet2.get_Range("A1", missing);
// create Pivot Cache and Pivot Table
pivotCache = (Excel.PivotCache)workbook.PivotCaches()
.Add(Excel.XlPivotTableSourceType.xlDatabase, pivotData);
pivotTable = (Excel.PivotTable)worksheet2.PivotTables()
.Add(PivotCache: pivotCache, TableDestination: pivotDestination, TableName: dataContext);
// Style Pivot Table
pivotTable.Format(Excel.XlPivotFormatType.xlReport2);
pivotTable.InGridDropZones = false;
pivotTable.SmallGrid = false;
pivotTable.TableStyle2 = "PivotStyleLight16";
// ROW FIELDS
Excel.PivotField rowField3 = (Excel.PivotField)pivotTable.PivotFields("SubTitle");
rowField3.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField3.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField3.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField3.LayoutCompactRow = true;
Excel.PivotField rowField2 = (Excel.PivotField)pivotTable.PivotFields("Title");
rowField2.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField2.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField2.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField2.LayoutCompactRow = true;
Excel.PivotField rowField1 = (Excel.PivotField)pivotTable.PivotFields("Project");
rowField1.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
rowField1.LayoutForm = Excel.XlLayoutFormType.xlOutline;
rowField1.LayoutSubtotalLocation = Excel.XlSubtototalLocationType.xlAtTop;
rowField1.LayoutCompactRow = true;
// FILTER FIELDS
Excel.PivotField pageField1 = (Excel.PivotField)pivotTable.PivotFields("Project");
pageField1.Orientation = Excel.XlPivotFieldOrientation.xlPageField;
pageField1.EnableMultiplePageItems = true;
// DATA FIELDS
int position = 1;
Excel.PivotField dataField1 = (Excel.PivotField)pivotTable.PivotFields("Value1");
dataField1.Orientation = Excel.XlPivotFieldOrientation.xlDataField;
dataField1.Function = Excel.XlConsolidationFunction.xlSum;
dataField1.NumberFormat = numberFormat;
dataField1.Position = position++;
Excel.PivotField dataField2 = (Excel.PivotField)pivotTable.PivotFields("Value2");
dataField2.Orientation = Excel.XlPivotFieldOrientation.xlDataField;
dataField2.Function = Excel.XlConsolidationFunction.xlSum;
dataField2.NumberFormat = numberFormat;
dataField2.Position = position++;
#endregion
// Close Excel
workbook.SaveAs("Interop.Excel_Pivot.xlsx");
workbook.Close();
excelApplication.Quit();
}
做到了!
var pivotLine = (Excel.PivotLine)pivotTable.PivotColumnAxis.PivotLines[2];
rowField2.AutoSortEx((int)Excel.XlSortOrder.xlDescending, "Summe von Value2", pivotLine, 1);
rowField3.AutoSortEx((int)Excel.XlSortOrder.xlDescending, "Summe von Value2", pivotLine, 1);
提示: 注意,给定的字符串 "Summe von " 是德语,在英语中将是 "Sum of " 和 Excel。 ;)