简体   繁体   English

打开XML SDK 2.0以按名称访问excel 2010工作表

[英]Open XML SDK 2.0 to get access to excel 2010 worksheet by name

I have an Excel 2010 spreadsheet that has 3 worksheets named Sheet1, Sheet2 and Sheet3. 我有一个Excel 2010电子表格,其中包含3个名为Sheet1,Sheet2和Sheet3的工作表。

I'm trying to get a reference to a worksheet by name. 我正在尝试按名称获取对工作表的引用。

I'm using the code: 我正在使用代码:

using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(FileName, true))
{
    //Access the main Workbook part, which contains all references 
    WorkbookPart workbookPart = myWorkbook.WorkbookPart;

    WorksheetPart worksheetPart = workbookPart.WorksheetParts.Last(); 

    // this gives me Sheet1
    SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
}

I am trying to get a reference to Sheet2, but I cannot find a way to do this. 我试图获得Sheet2的引用,但我找不到这样做的方法。

I'm getting closer, but I'm not there yet: 我越走越近了,但我还没到那里:

var x = workbookPart.Workbook.Sheets.Where(s=> s.GetAttribute("name", "").Value == "Sheet2").FirstOrDefault();

That gets me a reference to the sheet, but not to the data on the sheet 这让我得到了工作表的参考,但没有给工作表上的数据

Thanks 谢谢

What you really want is the WorksheetPart which is what contains the SheetData that you are looking for. 你真正想要的是WorksheetPart ,它包含你正在寻找的SheetData Grabbing the Sheets under the Workbook will only give you certain metadata about the worksheets. 抓取Workbook下的Sheets只会为您提供有关工作表的某些元数据。 Here is an example on how to grab that WorksheetPart (feel free to add error checking as you see fit as I assume the sheetName already exists by calling First and not FirstOrDefault ) 这里是如何抓住这样的例子WorksheetPart (随意添加你认为合适的错误检查,因为我承担sheetName已经通过调用存在, First ,而不是FirstOrDefault

public WorksheetPart GetWorksheetPart(WorkbookPart workbookPart, string sheetName)
{
    string relId = workbookPart.Workbook.Descendants<Sheet>().First(s => sheetName.Equals(s.Name)).Id;
    return (WorksheetPart)workbookPart.GetPartById(relId);
}

Then just use your code above to grab the correct SheetData reference and you will be able to find the data you want from there. 然后只需使用上面的代码来获取正确的SheetData引用,您就可以从那里找到所需的数据。

Here is some code to process a spreadsheet with a specific tab or sheet name and dump it to something like CSV. 下面是一些代码,用于处理具有特定选项卡或工作表名称的电子表格,并将其转储为CSV。 (I chose a pipe instead of comma). (我选择了一个管道而不是逗号)。

I wish it was easier to get the value from a cell, but I think this is what we are stuck with. 我希望从单元格中获取值更容易,但我认为这是我们所坚持的。 You can see that I reference the MSDN documents where I got most of this code. 您可以看到我参考了MSDN文档,其中包含了大部分代码。 That is what Microsoft recommends. 这是微软推荐的。

    /// <summary>
    /// Got code from: https://msdn.microsoft.com/en-us/library/office/gg575571.aspx
    /// </summary>
    [Test]
    public void WriteOutExcelFile()
    {
        var fileName = "ExcelFiles\\File_With_Many_Tabs.xlsx";
        var sheetName = "Submission Form"; // Existing tab name.
        using (var document = SpreadsheetDocument.Open(fileName, isEditable: false))
        {
            var workbookPart = document.WorkbookPart;
            var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName);
            var worksheetPart = (WorksheetPart)(workbookPart.GetPartById(sheet.Id));
            var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

            foreach (var row in sheetData.Elements<Row>())
            {
                foreach (var cell in row.Elements<Cell>())
                {
                    Console.Write("|" + GetCellValue(cell, workbookPart));
                }
                Console.Write("\n");
            }
        }
    }

    /// <summary>
    /// Got code from: https://msdn.microsoft.com/en-us/library/office/hh298534.aspx
    /// </summary>
    /// <param name="cell"></param>
    /// <param name="workbookPart"></param>
    /// <returns></returns>
    private string GetCellValue(Cell cell, WorkbookPart workbookPart)
    {
        if (cell == null)
        {
            return null;
        }

        var value = cell.CellFormula != null
            ? cell.CellValue.InnerText 
            : cell.InnerText.Trim();

        // If the cell represents an integer number, you are done. 
        // For dates, this code returns the serialized value that 
        // represents the date. The code handles strings and 
        // Booleans individually. For shared strings, the code 
        // looks up the corresponding value in the shared string 
        // table. For Booleans, the code converts the value into 
        // the words TRUE or FALSE.
        if (cell.DataType == null)
        {
            return value;
        }
        switch (cell.DataType.Value)
        {
            case CellValues.SharedString:

                // For shared strings, look up the value in the
                // shared strings table.
                var stringTable =
                    workbookPart.GetPartsOfType<SharedStringTablePart>()
                        .FirstOrDefault();

                // If the shared string table is missing, something 
                // is wrong. Return the index that is in
                // the cell. Otherwise, look up the correct text in 
                // the table.
                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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM