How to get Table/Cells data based on Defined Name/Defined name Range in Excel using OpenXML & C#

huangapple go评论73阅读模式
英文:

How to get Table/Cells data based on Defined Name/Defined name Range in Excel using OpenXML & C#

问题

以下是翻译好的内容:

我有一个包含多个工作表的Excel文件。在一个工作表中,我有2-3个类似数据表格的表格。
每个表格数据都有一个定义的名称。
现在我想根据定义的名称获取相应的表格数据。我对openXML不熟悉,有人能提供一些建议吗..?

示例:
在图像中,我有3个类似数据表格,每个表格都有一个定义的名称。如果选择任何一个定义的名称,它将选择相应的数据。

我正在尝试实现这一目标。根据定义的名称,我如何获取数据。

使用以下代码块,我正在获取定义的名称,但是,我如何获取与这些定义的名称关联的数据:

using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filePath, false))
{
    WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
    Sheets theSheets = workbookPart.Workbook.Sheets;
    foreach (Sheet item in theSheets)
    {
        if (item.Name.Value == "Sheet1")
        {
            var definedNames = GetDefinedNames(filePath);
            foreach(KeyValuePair<string, string> dn in definedNames)
            {
                Console.WriteLine(dn.Value);
            }
            WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(item.Id.Value);
            Worksheet workSheet = worksheetPart.Worksheet;
            SheetData sheetData = workSheet.GetFirstChild<SheetData>();
            IEnumerable<Row> rows = sheetData.Descendants<Row>();
            //这将包括标题行...
            foreach (Cell cell in rows.ElementAt(0))
            {
                if (!table.Columns.Contains(GetCellValue(spreadSheetDocument, cell)))
                {
                    table.Columns.Add(GetCellValue(spreadSheetDocument, cell));
                }
            }
            //这将包括单元格数据
            foreach (Row row in rows)
            {
                DataRow tempRow = table.NewRow();
                for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
                {
                    tempRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i));
                }
                table.Rows.Add(tempRow);
            }
        }
    }
}
table.Rows.RemoveAt(0);

使用以下方法,我正在获取定义的名称,但是,我如何获取与这些定义的名称关联的数据:

public static Dictionary<string, string> GetDefinedNames(string fileName)
{
    var returnValue = new Dictionary<string, string>();
    using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false))
    {
        WorkbookPart wbPart = document.WorkbookPart;
        DefinedNames definedNames = wbPart.Workbook.DefinedNames;
        if(definedNames != null)
        {
            foreach(DefinedName dn in definedNames)
            {
                if (!returnValue.ContainsKey(dn.Name.Value))
                {
                    returnValue.Add(dn.Name.Value, dn.Text);
                }
            }
        }
    }
    return returnValue;
}
英文:

I've One Excel file with multiple sheets. In one sheet I've 2-3 tables like data.
Each table data having one defined name.
Now I want to get the respective table data based on the defined name. I'm new to openXML can anyone suggest any Ideas..?

Example:
In the Image I'm having 3 table like data, each one having one defined name. If we select any of the defined name it'll select the respective data.

I'm trying to achieve this. Based on the define name how can I get the data.

using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filePath, false))
        {
            WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
            Sheets theSheets = workbookPart.Workbook.Sheets;
            foreach (Sheet item in theSheets)
            {
                if (item.Name.Value == &quot;Sheet1&quot;)
                {
                    var definedNames = GetDefinedNames(filePath);
                    foreach(KeyValuePair&lt;string, string&gt; dn in definedNames)
                    {
                        Console.WriteLine(dn.Value);
                    }
                    WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(item.Id.Value);
                    Worksheet workSheet = worksheetPart.Worksheet;
                    SheetData sheetData = workSheet.GetFirstChild&lt;SheetData&gt;();
                    IEnumerable&lt;Row&gt; rows = sheetData.Descendants&lt;Row&gt;();
                    //this will include header row...
                    foreach (Cell cell in rows.ElementAt(0))
                    {
                        if (!table.Columns.Contains(GetCellValue(spreadSheetDocument, cell)))
                        {
                            table.Columns.Add(GetCellValue(spreadSheetDocument, cell));
                        }
                    }
                    // this will include cell data
                    foreach (Row row in rows)
                    {
                        DataRow tempRow = table.NewRow();
                        for (int i = 0; i &lt; row.Descendants&lt;Cell&gt;().Count(); i++)
                        {
                            tempRow[i] = GetCellValue(spreadSheetDocument, row.Descendants&lt;Cell&gt;().ElementAt(i));
                        }
                        table.Rows.Add(tempRow);
                    }
                }
            }
        }
        table.Rows.RemoveAt(0);

By using below method I'm getting defined names but, How can I get the data which is tagged to those defined names:

public static Dictionary&lt;string, string&gt; GetDefinedNames(string fileName)
    {
        var returnValue = new Dictionary&lt;string, string&gt;();
        using (SpreadsheetDocument document =
            SpreadsheetDocument.Open(fileName, false))
        {
            WorkbookPart wbPart = document.WorkbookPart;
            DefinedNames definedNames = wbPart.Workbook.DefinedNames;
            if(definedNames != null)
            {
                foreach(DefinedName dn in definedNames)
                {
                    if (!returnValue.ContainsKey(dn.Name.Value))
                    {
                        returnValue.Add(dn.Name.Value, dn.Text);
                    }
                }
            }
        }
        return returnValue;
    }

答案1

得分: 1

OpenXML不提供这方面的功能。您可能最好使用一些高级API,如ClosedXML等。

如果您坚持要使用OpenXML,以下是您需要做的:

DefinedName的Text属性包含单元格范围,形式为"SHEETNAME!$A$1:$C$3"。请注意,它可以包含多个范围,用逗号分隔。另外,工作表的名称可以用方括号括起来。
解析该字符串将为您提供范围中单元格的左上角和右下角地址。

然后,您需要通过它们的地址获取单元格的功能。OpenXML也不提供这个功能。您已经有了读取单元格值的代码。单元格的CellReference属性包含单元格的地址("A1") - 现在您需要检查该地址是否在DefinedName的范围内。

英文:

OpenXML does not provide functionality for that. You might be better off using some higher level API like ClosedXML etc.

If you insist on using OpenXML, here is what you would need to do:

The DefinedName's Text property contains the cell range in the form "SHEETNAME!$A$1:$C$3". Note that it can contain multiple ranges, separated by commas. Also, the name of the sheet can be surrounded by square brackets.
Parsing that string gives you the left-upper and the right-bottom adresses of the cells in the ranges.

Then you need functionality to get cells by their adresses. OpenXML does not provide that either. You already have the code for reading cell values. The CellReference property of the Cell contains the adress of the cell ("A1") - now you need check if the adress is within the range from the DefinedName.

答案2

得分: 0

不要使用OpenXML SDK,而是使用高级库如EPPlus或ClosedXML。OpenXML SDK太底层了,因为它严格遵循XML结构。

在EPPlus中,您可以使用以下代码读取命名表的内容:

using (var package = new ExcelPackage(file))
{
    var sheet = package.Workbook.Worksheets["Tables"];

    var myTable = sheet.Tables["myTable"];
    var range = myTable.Range;
    ...

    package.Save();
}

EPPlus提供了将数据提取到DataTable或List,保存为CSV、JSON或HTML的方法。

var table = sheet.Tables["myTable"];
var items = table.ToCollection<TestDTO>();
英文:

Instead of using the OpenXML SDK use a high-level library like EPPlus or ClosedXML. The OpenXML SDK is too low-level as it follows the XML structure closely.

In EPPlus you can read the contents of a named table with just sheet.Tables[&quot;myTable&quot;],for example:

using(var package = new ExcelPackage(file))
{
    var sheet = package.Workbook.Worksheets[&quot;Tables&quot;];

    var myTable = sheet.Tables[&quot;myTable&quot;];   
    var range=myTable.Range;
    ...

    package.Save();
}

EPPlus offers methods to extract the data into a DataTable or List<T>, save it to CSV, JSON or HTML.

var table=sheet.Tables[&quot;myTable&quot;];
var items=table.ToCollection&lt;TestDTO&gt;();

huangapple
  • 本文由 发表于 2023年6月26日 21:44:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557275.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定