OpenXML SDK:使Excel重新计算公式

我通过Microsoft Office OpenXML SDK 2.0更新Excel电子表格的某些单元格。 更改值使所有单元格包含依赖于更改的单元格无效的公式。 但是,由于caching的值,Excel不会重新计算公式,即使用户单击“立即计算”。

通过SDK使整个工作簿的所有相关单元失效的最佳方法是什么? 到目前为止,我在http://cdonner.com/introduction-to-microsofts-open-xml-format-sdk-20-with-a-focus-on-excel-documents.htm上find了以下代码片段:

public static void ClearAllValuesInSheet (SpreadsheetDocument spreadSheet, string sheetName) { WorksheetPart worksheetPart = GetWorksheetPartByName(spreadSheet, sheetName); foreach (Row row in worksheetPart.Worksheet. GetFirstChild().Elements()) { foreach (Cell cell in row.Elements()) { if (cell.CellFormula != null && cell.CellValue != null) { cell.CellValue.Remove(); } } } worksheetPart.Worksheet.Save(); } 

除了这个片段不能编译的事实,它有两个限制:

  • 它仅使单张纸无效,但其他纸张可能包含相关公式
  • 它不考虑任何依赖关系。

我正在寻找一种有效的方法(特别是,只使依赖于某个单元格值的单元格无效),并考虑所有表单。

更新:

在此期间,我设法编译并运行代码,并删除所有工作簿表中的caching值。 (请参阅答案)。我仍然对更好/替代解决scheme感兴趣,特别是如何删除实际依赖于更新的单元格的单元格的caching值。

 spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true; spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true; 

为我工作!

我用这个

  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()) ; } 

这刷新caching的值

招呼

由于它部分解决了我的问题,目前似乎还没有更好的解决scheme,将这个代码块从问题中移出来作为答案…这就是新代码的外观:

 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(); } } } 

您需要将工作表保存在最后,这对我有效。

 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(); }