Domanda

I have looked at all the previous answers to the similar questions in SO but those answers do not work. I pass in the value in excel and want the formula cell to recalculate but its still showing up the old value.

I have used the 2 techniques 1) remove the calculated value from the cell 2)Open and close the file programmatically. Both of them don't work for me. Here is my code. Please help.

            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);
            }
È stato utile?

Soluzione

From the by you provided code snippet I miss the essential part from the blog you referred to.

As stated in that blog OpenXML can only be used for creating/reading/updating and deleting the storage format for OpenXML compatible applications. You don't get the actual application engine. To achieve what you want you either need to install Excel on your server so you can leverage Microsoft.Office.Interop.Excel namespace and it's Application COM interface or rely on the end-users Excel application to do the recalculation when openening the updated excel sheet.

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

Please do realize that if you need this to run on a server (for example because you need the calculated results in a webpage) you might run into serious performance trouble, memory, I/O and CPU wise. In that case I would rather implement the calculation rules/formulas in C#.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top