【问题标题】:open xml sdk excel formula recalculate after cell removal打开 xml sdk excel 公式在单元格删除后重新计算
【发布时间】:2014-03-10 16:59:20
【问题描述】:

我有一个公式单元格 C4,在我在另一个单元格 C2 中输入值后需要重新计算。但 C4 不断被缓存并不断返回旧的缓存值。

我在 SO 上多次问过这个问题,但我没有得到任何帮助。我正在尽我所能。这是我在 msdn 网站上找到的。

使用前面代码清单中的方法,生成 该报告现在是一个获取投资组合数据的过程 重复调用 UpdateValue 来创建报告。确实,如果你 添加必要的代码来做到这一点,除了 一个问题 - 任何包含引用单元格的公式的单元格 通过 Open XML 操作更改其值的不显示 正确的结果。这是因为 Excel 缓存了公式的结果 细胞内。因为 Excel 认为它缓存了正确的值, 它不会重新计算单元格。即使你有自动计算 打开或如果您按 F9 强制手动重新计算,Excel 不重新计算单元格。解决这个问题的方法是删除 从这些单元格中缓存值,以便 Excel 将值重新计算为 在 Excel 中打开文件后。添加 RemoveCellValue 方法 如下例所示向 PortfolioReport 类提供 这个功能。

基于上面的 MSDN 解释。我尝试在更新单元格之前删除代码。在我更新单元格之后。在我阅读公式单元格之前,在我阅读公式单元格之后,但在我阅读公式单元格后我不断收到以下错误。

System.NullReferenceException:对象引用未设置为实例 一个对象。

这是我的代码...

    string filename = Server.MapPath("/") + "MyExcelData.xlsx";



    using (SpreadsheetDocument document = SpreadsheetDocument.Open(filename, true))
    {


        Sheet sheet = document.WorkbookPart.Workbook.Descendants<Sheet>().SingleOrDefault(s => s.Name == "myRange1");
        if (sheet == null)
        {
            throw new ArgumentException(
                String.Format("No sheet named {0} found in spreadsheet {1}", "myRange1", filename), "sheetName");
        }
        WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheet.Id);
        Worksheet ws = worksheetPart.Worksheet; // ((WorksheetPart)(worksheetPart.GetPartById(sheet.Id))).Worksheet;
        Cell cell = InsertCellInWorksheet(ws, "C4");

        // If there is a cell value, remove it to force a recalculation
        // on this cell.
        if (cell.CellValue != null)
        {
            cell.CellValue.Remove();
        }

        // Save the worksheet.
        ws.Save();
        document.Close();
    }



    // getting 2 numbers in excel sheet, saving, and closing it.

    using (SpreadsheetDocument document = SpreadsheetDocument.Open(filename, true))
    {


        Sheet sheet = document.WorkbookPart.Workbook.Descendants<Sheet>().SingleOrDefault(s => s.Name == "myRange1");
        if (sheet == null)
        {
            throw new ArgumentException(
                String.Format("No sheet named {0} found in spreadsheet {1}", "myRange1", filename), "sheetName");
        }
        WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheet.Id);


        int rowIndex = int.Parse("C3".Substring(1));

        Row row = worksheetPart.Worksheet.GetFirstChild<SheetData>().
                Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex);

        Cell cell3 = row.Elements<Cell>().FirstOrDefault(c => "C3".Equals(c.CellReference.Value));
        if (cell3 != null) 
        {
            cell3.CellValue = new CellValue("16");
            cell3.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.Number); 
        }

        worksheetPart.Worksheet.Save();
        document.Close();

    }

    // getting the result out of excel.
    using (SpreadsheetDocument document = SpreadsheetDocument.Open(filename, false))
    {
        document.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
        document.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;

        Sheet sheet = document.WorkbookPart.Workbook.Descendants<Sheet>().SingleOrDefault(s => s.Name == "myRange1");
        if (sheet == null)
        {
            throw new ArgumentException(
                String.Format("No sheet named {0} found in spreadsheet {1}", "myRange1", filename), "sheetName");
        }



        WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheet.Id);

        int rowIndex = int.Parse("C4".Substring(1));

        Row row = worksheetPart.Worksheet.GetFirstChild<SheetData>().
                Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex);

        Cell cell = row.Elements<Cell>().FirstOrDefault(c => "C4".Equals(c.CellReference.Value));

        d.Average = Convert.ToDouble(cell.CellValue.InnerText);

    }

【问题讨论】:

    标签: c# excel asp.net-mvc-4 openxml openxml-sdk


    【解决方案1】:

    问题似乎是您在没有打开 Excel 的情况下直接修改 Excel 数据文件。由于 Excel 只能在打开时跟踪公式依赖关系,因此它不知道在您更改数据时需要重新计算,而 Excel 并不知道您已经这样做了。

    3 种可能的解决方案是:
    1)从文件中删除计算链部分(未测试)
    2) 对文件进行更改后,使用互操作/自动化打开 Excel 并请求完整计算(或者如果您还更改/创建公式,则使用依赖关系重建进行完整计算)
    3) 将 fullcalculationonload 属性设置为 true :这应该会导致 Excel 在打开文件时进行完整计算

    【讨论】:

      【解决方案2】:

      我认为你已经删除了 C4 的 cellValue,首先你必须创建 cellValue 然后你可以对其执行任何操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-09
        • 1970-01-01
        • 1970-01-01
        • 2014-11-25
        • 1970-01-01
        • 2017-09-04
        • 1970-01-01
        相关资源
        最近更新 更多