2014-01-23 134 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