如何使用Interop.Excel(C#)对数据透视表(DESC值)进行排序

时间:2019-01-24 08:09:51

标签: c# sorting pivot-table excel-interop

如何使用Interop.Excel和C#对数据透视表进行排序? 我完全像我想要的那样获得了数据透视表的生成,但是却在排序方面苦苦挣扎...

应该进行排序,对于“标题”和“子标题”,“ 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();
}

Screenshots

1 个答案:

答案 0 :(得分:0)

做到了!

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”是德语,并且在Excel中将是英语的“ Sum of”。 ;)