2014-01-23 1 views
3

Я просмотрел все предыдущие ответы на подобные вопросы в SO, но эти ответы не работают. Я передаю значение в excel и хочу, чтобы ячейка формулы пересчитывала, но все еще показывала старое значение.open xml sdk excel formula recalculate cache issue

Я использовал 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(); 

Пожалуйста понимают, что если вам это нужно запускать на сервере (например, потому что нужно вычисленных результатов в веб-страницы), вы можете столкнуться с серьезными неприятностями производительности, памяти, ввода/Вывода и процессора. В этом случае я предпочел бы реализовать правила расчета/формулы в C#.

+0

Спасибо, Рене, я столкнулся с тем, что вы упомянули, но не понимал важность ссылки на excel и workbook как объекты Microsoft.Interop .... Я попробовал, и он работает как красивый. Большое вам спасибо за помощь. Я очень ценю это. Это *** работает **** –

+0

Привет, Рене, что это лучший способ для работы над окном веб-облака windows azure без установки excel на веб-сервер? Заранее спасибо. –

+0

Я не вижу или не знаю, как это сделать, см. [Также эту статью в KB] (http://support.microsoft.com/kb/257757/en-us). Как я уже сказал, если вам нужны расчеты, серверы реализуют это на C#. – rene