2014-01-23 86 views
3

我已经查看了所有以前对SO中类似问题的回答,但这些回答不起作用。我在excel中传递值,并希望公式单元格重新计算,但仍显示旧值。打开xml sdk 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); 
      } 
+0

你试过'ForceFullCalculation = true; '在第一次打开电子表格后的第一个代码块中? – rene

+0

是的,我只是试了一下,它不起作用。我过去3天一直在发布相同的问题,但仍然没有人解决不了问题。谈论挫折!!!!! –

回答

1

从你提供的代码片段中,我想念你引用的博客的重要部分。

正如该博客所述,OpenXML只能用于创建/读取/更新和删除OpenXML兼容应用程序的存储格式。你没有得到实际的应用程序引擎。为了达到你想要的目的,你需要在你的服务器上安装Excel,这样你就可以利用Microsoft.Office.Interop.Excel namespace和它的Application 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#中实现计算规则/公式。

+0

谢谢rene,我遇到了你提到的博客,但没有意识到将excel和工作簿作为Microsoft.Interop ...对象的重要性。我已经尝试过,它像美丽的作品。非常感谢你的帮助..我非常感谢它。它***的作品**** –

+0

嗨雷内,什么是最好的方式来这个工作在Windows Azure网络云应用程序出去安装Excel的Web服务器?先谢谢你。 –

+0

我没有看到或知道一种方法来实现这一点,请参见[也是这篇知识库文章](http://support.microsoft.com/kb/257757/en-us)。正如我所说的,如果您需要在C#中使用计算服务器实现它。 – rene