通过打开的xml sdk linq查询获取具有行和列位置的excel单元格值

Rus*_*ich 7 c# xml linq

任何人都知道如何通过开放的XML SDK 2.0获得excel单元格值,知道行和列位置,例如(A2),通过Linq?

cvr*_*man 7

因此,excel直接存储单元格值,或者如果它是一个字符串,则存储在称为SharedString表的公共数据结构中.

在下面的示例中,我们首先使用linq将单元格放在特定地址,然后将其传递给另一个函数以获取单元格的值.

另请注意,您必须在每个阶段添加空检查以确定行/列是否存在

using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace TestOpenXmlSDK
{
    class Program
    {
        static void Main(string[] args)
        {
            string pathSource = @"D:\sample.xlsx";
            using (FileStream fsSource = new FileStream(pathSource, FileMode.Open, FileAccess.Read))
            {
                byte[] bytes = new byte[fsSource.Length];
                fsSource.Read(bytes, 0, (int)fsSource.Length);
                using (MemoryStream mem = new MemoryStream())
                {
                    mem.Write(bytes, 0, (int)bytes.Length);
                    using (SpreadsheetDocument excelDocument = SpreadsheetDocument.Open(mem, true))
                    {
                        var wbPart = excelDocument.WorkbookPart;
                        var wsPart = wbPart.WorksheetParts.First();
                        var sheetData = wsPart.Worksheet.GetFirstChild<SheetData>();

                        var cellValue = GetCellValue(GetCell(sheetData, "B2"), wbPart);
                    }
                }
            }
        }

        public static Cell GetCell(SheetData sheetData, string cellAddress)
        {
            uint rowIndex = uint.Parse(Regex.Match(cellAddress, @"[0-9]+").Value);
            return sheetData.Descendants<Row>().FirstOrDefault(p => p.RowIndex == rowIndex).Descendants<Cell>().FirstOrDefault(p => p.CellReference == cellAddress);
        }

        public static string GetCellValue(Cell cell, WorkbookPart wbPart)
        {
            string value = cell.InnerText;
            if (cell.DataType != null)
            {
                switch (cell.DataType.Value)
                {
                    case CellValues.SharedString:
                        var stringTable = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
                        if (stringTable != null)
                        {
                            value = stringTable.SharedStringTable.ElementAt(int.Parse(value)).InnerText;
                        }
                        break;

                    case CellValues.Boolean:
                        switch (value)
                        {
                            case "0":
                                value = "FALSE";
                                break;
                            default:
                                value = "TRUE";
                                break;
                        }
                        break;
                }
            }
            return value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)