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