Откройте сводную таблицу Xml: как читать итоги и промежуточные итоги, чтобы их отобразить? - PullRequest
3 голосов
/ 27 мая 2020

Я пытаюсь создать сводную таблицу Excel полностью с нуля, используя Open Xml.

Я успешно создал саму сводную таблицу (создал определение сводной таблицы, определение кеша, все записи кеша, pivotFields, RowItems и т. д. c. и c.).

Но как мне отобразить какие-либо данные? Как прочитать расчеты сводной таблицы, чтобы записать эти значения в ячейки?

Например:

Example Pivot Table definition and Pivot Table data

  • «общая сумма» составляет 86 631,62 доллара.
  • Два промежуточных итога: 61 631,12 доллара и 25 000,50 долларов. "в ячейку.

    Если я создаю ячейку самостоятельно (используя Open Xml), как мне« запросить »эти значения, позволяя сводной таблице вычислить их для меня?

    PS: Я широко использую Open Xml Productivity Tool ... но он также просто "жестко кодирует" итоги и промежуточные итоги ... без каких-либо подсказок, как / где на самом деле были рассчитаны значения.

1 Ответ

4 голосов
/ 01 июня 2020

Вы можете использовать формулу ячейки, если не хотите использовать EPPlus:

cell.DataType = new EnumValue<CellValue.Number);
cell.CellFormula = new CellFormula($"=SUBTOTAL{"109"}{rowName}");

//force full recalculation of the cells
workbookPart.workbook.CalculationProperties.ForceFullCalculation = true;
workbookPart.workbook.CalculationProperties.FullCalculationLoad = true;

Таким образом, вы можете использовать любую формулу через Open Xml, чтобы вычислить все, что вам нужно.

Для загрузки в DataTable:

DataTable dt = new DataTable();

using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(@"..\..\example.xlsx", false))
{

    WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
    IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
    string relationshipId = sheets.First().Id.Value;
    WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
    Worksheet workSheet = worksheetPart.Worksheet;
    SheetData sheetData = workSheet.GetFirstChild<SheetData>();
    IEnumerable<Row> rows = sheetData.Descendants<Row>();

    foreach (Cell cell in rows.ElementAt(0))
    {
        dt.Columns.Add(GetCellValue(spreadSheetDocument, cell));
    }

    foreach (Row row in rows) //this will also include your header row...
    {
        DataRow tempRow = dt.NewRow();

        for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
        {
            tempRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i-1));
        }

        dt.Rows.Add(tempRow);
    }

}

...