打开xml sdk excel公式重新计算缓存问题

时间:2014-01-23 14:57:57

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

我已经查看了SO中类似问题的所有先前答案,但这些答案不起作用。我传入excel中的值并希望公式单元格重新计算,但它仍然显示旧值。

我使用了2种技术1)从单元格中删除计算值2)以编程方式打开和关闭文件。它们都不适合我。这是我的代码。请帮忙。

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



            // 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("13");
                    cell3.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.Number); 
                }

                document.WorkbookPart.WorksheetParts
   .SelectMany(part => part.Worksheet.Elements<SheetData>())
   .SelectMany(data => data.Elements<Row>())
   .SelectMany(row1 => row1.Elements<Cell>())
   .Where(cell => cell.CellFormula != null && cell.CellValue != null)
   .ToList()
   .ForEach(cell => cell.CellValue.Remove());

                worksheetPart.Worksheet.Save();

            }



            // 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));

                calculatedvalue = Convert.ToDouble(cell.CellValue.InnerText);
            }

1 个答案:

答案 0 :(得分:1)

根据您提供的代码段,我错过了您所引用的博客中的重要部分。

正如博客中所述,OpenXML只能用于创建/读取/更新和删除OpenXML兼容应用程序的存储格式。您没有获得实际的应用程序引擎。要实现您的目标,您需要在服务器上安装Excel,这样您就可以利用Microsoft.Office.Interop.Excel namespaceApplication COM接口,或者依赖最终用户Excel应用程序在打开更新的Excel时进行重新计算片材。

code copied and text adapted from this blog

var excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbook workbook = excelApp.Workbooks.Open(Path.GetFullPath(_filePath));
workbook.Close(true);
excelApp.Quit();

请注意,如果您需要在服务器上运行(例如,因为您需要在网页中计算结果),您可能会遇到严重的性能问题,内存,I / O和CPU。在这种情况下,我宁愿在C#中实现计算规则/公式。