簡體   English   中英

openxml sdk excel如何解析和計算公式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM