[英]openxml sdk excel how to parse and calculate formula
我在excel文件中有公式單元格,其公式為= SUM(C2:C3)。
從雲端遠程Web服務器上托管的Web應用程序,沒有安裝Excel,我會傳遞C2和C3的值。
我還可以確定excel中的確切公式。 如何在c#中以編程方式解析此公式,以便如果C2和C3的輸入值分別為2和4,我可以得到6的結果?
如果公式非常復雜,在asp.net mvc應用程序中解析公式並在服務器端的C#中計算它的最佳方法是什么?
在這種情況下,代碼示例對我非常有益。
如果您提供打開excel文件的工具並將其內容翻譯為html,則必須處理計算。
如果文件“創建良好”,例如使用Excel手動創建,則可以確保不需要管理公式的計算,因為excel可以完成這一操作,並將公式存儲在CellFormula的子元素中,並生成CellValue的子元素(請參閱方法GetValue_D11())。 所以基本上你只需要顯示結果..它總是一個字符串。
不幸的是,如果你想保持行為,你必須處理樣式和數據類型。
實際上,您必須構建一個復雜的基於Web的電子表格查看器/編輯器。
以下是檢索字符串值和公式值的“固定”示例(完全不是動態的)。 如果你想運行測試一定要下載該文件( http://www.devnmore.com/share/Test.xlsx ),否則它無法運行。
ShowValuesSample svs = new ShowValuesSample("yourPath\\Test.xlsx");
String[] test = svs.GetDescriptions_A2A10();
Double grandTotal = svs.GetValue_D11();
ShowValuesSample類:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml.Packaging;
using Ap = DocumentFormat.OpenXml.ExtendedProperties;
using Vt = DocumentFormat.OpenXml.VariantTypes;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using A = DocumentFormat.OpenXml.Drawing;
using System.Globalization;
namespace TesterApp
{
public class ShowValuesSample
{
public String FileName { get; private set; }
private SpreadsheetDocument _ExcelDocument = null;
public SpreadsheetDocument ExcelDocument
{
get
{
if (_ExcelDocument == null)
{
_ExcelDocument = SpreadsheetDocument.Open(FileName, true);
}
return _ExcelDocument;
}
}
private SheetData _SheetDataOfTheFirstSheet = null;
public SheetData SheetDataOfTheFirstSheet
{
get
{
if (_SheetDataOfTheFirstSheet == null)
{
WorksheetPart shPart = ExcelDocument.WorkbookPart.WorksheetParts.ElementAt(0);
Worksheet wsh = shPart.Worksheet;
_SheetDataOfTheFirstSheet = wsh.Elements<SheetData>().ElementAt(0);
}
return _SheetDataOfTheFirstSheet;
}
}
private SharedStringTable _SharedStrings = null;
public SharedStringTable SharedStrings
{
get
{
if (_SharedStrings == null)
{
SharedStringTablePart shsPart = ExcelDocument.WorkbookPart.SharedStringTablePart;
_SharedStrings = shsPart.SharedStringTable;
}
return _SharedStrings;
}
}
public ShowValuesSample(String fileName)
{
FileName = fileName;
}
//In the file descriptions are stored as sharedString
//so cellValue it's the zeroBased index of the sharedStringTable
//in my example i saved 9 different values
//sharedstring it's a trick to reduce size of a file obiouvsly writing
//repetitive string just once
public String[] GetDescriptions_A2A10()
{
String[] retVal = new String[9];
for (int i = 0; i < retVal.Length; i++)
{
Row r = SheetDataOfTheFirstSheet.Elements<Row>().ElementAt(i + 1);
Cell c = r.Elements<Cell>().ElementAt(0);
Int32 shsIndex = Convert.ToInt32(c.CellValue.Text);
SharedStringItem shsItem = SharedStrings.Elements<SharedStringItem>().ElementAt(shsIndex);
retVal[i] = shsItem.Text.Text;
}
return retVal;
}
//The value it's stored beacause excel does
//To be sure it's correct you should perform all calculations
//In this case i'm sure Excel didn't stored the wrong value so..
public Double GetValue_D11()
{
Double retVal = 0.0d;
Int32 cellIndex = 0;
//cellIndex it's 0 and not 3, cause A11, B11, C11 are empty cells
//Another issue to deal with ;-)
Cell c = SheetDataOfTheFirstSheet.Elements<Row>().ElementAt(10).Elements<Cell>().ElementAt(cellIndex);
//as example take a look at the value of storedFormula
String storedFormula = c.CellFormula.Text;
String storedValue = c.CellValue.Text;
NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberDecimalSeparator = ".";
provider.NumberGroupSeparator = ",";
provider.NumberGroupSizes = new Int32[] { 3 };
retVal = Convert.ToDouble(storedValue, provider);
return retVal;
}
}
}
spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
為我工作。
我擔心這是不可能的。 在Open XML中,您可以閱讀或更改公式。 但是你處理公式並通過打開xml獲得結果。
更改公式的C2和C3的值,然后將其保存在打開的xml中,現在通過Excel App打開文檔。 將計算並顯示這些值。
請參閱此SO帖子,與此問題相關, 打開xml sdk excel公式重新計算緩存問題
請參閱這篇文章http://openxmldeveloper.org/discussions/formats/f/14/p/1806/158153.aspx
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.