OpenXML SDK: Make Excel recalculate formula

前端 未结 5 417
旧巷少年郎
旧巷少年郎 2020-11-30 06:15

I update some cells of an Excel spreadsheet through the Microsoft Office OpenXML SDK 2.0. Changing the values makes all cells containing formula that depend on the changed c

相关标签:
5条回答
  • 2020-11-30 06:34

    Since it partially solves my problem and there seems to be no better solution so far, moved that codeblock out from the question to an answer... This is how the new code looks like:

    foreach (WorksheetPart worksheetPart in spreadSheet.WorkbookPart.WorksheetParts)
    {
        foreach (Row row in
                worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements())
        {
            foreach (Cell cell in row.Elements())
            {
                if (cell.CellFormula != null && cell.CellValue != null)
                    cell.CellValue.Remove();
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 06:35
    spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
    spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
    

    Works for me!

    0 讨论(0)
  • 2020-11-30 06:37

    You need to save the worksheet at the end, This worked for me.

    foreach (WorksheetPart worksheetPart in spreadSheet.WorkbookPart.WorksheetParts) {
        foreach (Row row in
                worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements()) {
            foreach (Cell cell in row.Elements()) {
                if (cell.CellFormula != null && cell.CellValue != null)
                    cell.CellValue.Remove();
            }
        }
        worksheetPart.Worksheet.Save();
    }
    
    0 讨论(0)
  • 2020-11-30 06:42

    I use this

        static void FlushCachedValues(SpreadsheetDocument doc)
        {
            doc.WorkbookPart.WorksheetParts
                .SelectMany(part => part.Worksheet.Elements<SheetData>())
                .SelectMany(data => data.Elements<Row>())
                .SelectMany(row => row.Elements<Cell>())
                .Where(cell => cell.CellFormula != null)
                .Where(cell => cell.CellValue != null)
                .ToList()
                .ForEach(cell => cell.CellValue.Remove())
                ;
        }
    

    This flushes the cached values

    greets

    0 讨论(0)
  • 2020-11-30 06:50

    Alternatively, you can change the formulas to use INDIRECT operator. Especially useful if you are using SAX + template files approach. Since this solution does not require changing your code, only template excel files. Please refer to my solution here - Set xlsx to recalculate formulae on open

    0 讨论(0)
提交回复
热议问题