Compartilhar via


Obter um cabeçalho de coluna num documento de folha de cálculo

Este tópico mostra como utilizar as classes no SDK Open XML para o Office para obter um cabeçalho de coluna num documento de folha de cálculo programaticamente.

Estrutura básica de um documento de folha de cálculoML

A estrutura de documentos básica de um SpreadsheetML documento consiste nos Sheets elementos e Sheet , que referenciam as folhas de cálculo no livro. Um arquivo XML separado é criado para cada planilha. Por exemplo, o SpreadsheetML para um Workbook que tem duas folhas de cálculo com o nome MySheet1 e MySheet2 está localizado no ficheiro Workbook.xml e é apresentado no seguinte exemplo de código.

    <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
    <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
        <sheets>
            <sheet name="MySheet1" sheetId="1" r:id="rId1" /> 
            <sheet name="MySheet2" sheetId="2" r:id="rId2" /> 
        </sheets>
    </workbook>

Os ficheiros XML da folha de cálculo contêm um ou mais elementos de nível de bloco, como SheetData representa a tabela de células e contém um ou mais Row elementos. A row contém um ou mais Cell elementos. Cada célula contém um CellValue elemento que representa o valor da célula. Por exemplo, o para a SpreadsheetML primeira folha de cálculo num livro, que tem apenas o valor 100 na célula A1, está localizado no ficheiro Sheet1.xml e é apresentado no seguinte exemplo de código.

    <?xml version="1.0" encoding="UTF-8" ?> 
    <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
        <sheetData>
            <row r="1">
                <c r="A1">
                    <v>100</v> 
                </c>
            </row>
        </sheetData>
    </worksheet>

Com o SDK Open XML, pode criar a estrutura do documento e o conteúdo que utiliza classes com tipos fortes que correspondem a SpreadsheetML elementos. Pode encontrar estas classes no DocumentFormat.OpenXML.Spreadsheet espaço de nomes. A tabela seguinte lista os nomes das classes que correspondem aos workbookelementos , sheets, sheet, worksheete sheetData .

Elemento SpreadsheetML Abrir Classe SDK XML Descrição
<workbook/> DocumentFormat.OpenXML.Spreadsheet.Workbook O elemento raiz para a parte do documento principal.
<sheets/> DocumentFormat.OpenXML.Spreadsheet.Sheets O contêiner para as estruturas de nível de bloco, como sheet, fileVersion e outras indicadas na especificação ISO/IEC 29500.
<sheet/> DocumentFormat.OpenXml.Spreadsheet.Sheet Uma planilha que aponta para um arquivo de definição de planilha.
<worksheet/> DocumentFormat.OpenXML.Spreadsheet. Planilha Um arquivo de definição de planilha que contém os dados de planilha.
<sheetData/> DocumentFormat.OpenXML.Spreadsheet.SheetData A tabela de células, agrupadas por linhas.
<row/> DocumentFormat.OpenXml.Spreadsheet.Row Uma linha na tabela de células.
<c/> DocumentFormat.OpenXml.Spreadsheet.Cell Uma célula em uma linha.
<v/> DocumentFormat.OpenXml.Spreadsheet.CellValue O valor de uma célula.

Como funciona o código de exemplo

O código neste procedimento consiste em três métodos (funções no Visual Basic): GetColumnHeading, GetColumnNamee GetRowIndex. Os dois últimos métodos são chamados a GetColumnHeading partir do método .

O GetColumnName método utiliza o nome da célula como um parâmetro. Analisa o nome da célula para obter o nome da coluna ao criar uma expressão regular para corresponder à parte do nome da coluna do nome da célula. Para obter mais informações sobre expressões regulares, veja Elementos de Linguagem de Expressão Regular.

// Create a regular expression to match the column name portion of the cell name.
Regex regex = new Regex("[A-Za-z]+");
Match match = regex.Match(cellName);

return match.Value;

O GetRowIndex método utiliza o nome da célula como um parâmetro. Analisa o nome da célula para obter o índice de linhas ao criar uma expressão regular para corresponder à parte do índice da linha do nome da célula.

// Create a regular expression to match the row index portion the cell name.
Regex regex = new Regex(@"\d+");
Match match = regex.Match(cellName);

return uint.Parse(match.Value);

O GetColumnHeading método utiliza três parâmetros, o caminho completo para o ficheiro de folha de cálculo de origem, o nome da folha de cálculo que contém a coluna especificada e o nome de uma célula na coluna para a qual obter o cabeçalho.

O código obtém o nome da coluna da célula especificada ao chamar o GetColumnName método . O código também obtém as células na coluna e ordena-as por linha com o GetRowIndex método .

// Get the column name for the specified cell.
string columnName = GetColumnName(cellName);

// Get the cells in the specified column and order them by row.
IEnumerable<Cell> cells = worksheetPart.Worksheet.Descendants<Cell>().Where(c => string.Compare(GetColumnName(c.CellReference?.Value), columnName, true) == 0)
    .OrderBy(r => GetRowIndex(r.CellReference) ?? 0);

Se a coluna especificada existir, obtém a primeira célula na coluna com o First método . A primeira célula contém o cabeçalho. Caso contrário, a coluna especificada não existe e o método devolve null / Nothing

if (cells.Count() == 0)
{
    // The specified column does not exist.
    return null;
}

// Get the first cell in the column.
Cell headCell = cells.First();

Se o conteúdo da célula estiver armazenado no SharedStringTablePart objeto, obtém os itens de cadeia partilhados e devolve o conteúdo do cabeçalho da coluna com o Parse método . Se o conteúdo da célula não estiver no SharedStringTable objeto, devolve o conteúdo da célula.

// If the content of the first cell is stored as a shared string, get the text of the first cell
// from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
if (headCell.DataType is not null && headCell.DataType.Value == CellValues.SharedString && int.TryParse(headCell.CellValue?.Text, out int index))
{
    SharedStringTablePart shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
    SharedStringItem[] items = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();

    return items[index].InnerText;
}
else
{
    return headCell.CellValue?.Text;
}

Código de exemplo

A seguir está o código de exemplo completo em C# e em Visual Basic.

static string? GetColumnHeading(string docName, string worksheetName, string cellName)
{
    // Open the document as read-only.
    using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, false))
    {
        IEnumerable<Sheet>? sheets = document.WorkbookPart?.Workbook.Descendants<Sheet>().Where(s => s.Name == worksheetName);

        if (sheets is null || sheets.Count() == 0)
        {
            // The specified worksheet does not exist.
            return null;
        }

        string? id = sheets.First().Id;

        if (id is null)
        {
            // The worksheet does not have an ID.
            return null;
        }

        WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart!.GetPartById(id);

        // Get the column name for the specified cell.
        string columnName = GetColumnName(cellName);

        // Get the cells in the specified column and order them by row.
        IEnumerable<Cell> cells = worksheetPart.Worksheet.Descendants<Cell>().Where(c => string.Compare(GetColumnName(c.CellReference?.Value), columnName, true) == 0)
            .OrderBy(r => GetRowIndex(r.CellReference) ?? 0);

        if (cells.Count() == 0)
        {
            // The specified column does not exist.
            return null;
        }

        // Get the first cell in the column.
        Cell headCell = cells.First();

        // If the content of the first cell is stored as a shared string, get the text of the first cell
        // from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
        if (headCell.DataType is not null && headCell.DataType.Value == CellValues.SharedString && int.TryParse(headCell.CellValue?.Text, out int index))
        {
            SharedStringTablePart shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
            SharedStringItem[] items = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();

            return items[index].InnerText;
        }
        else
        {
            return headCell.CellValue?.Text;
        }
    }
}
// Given a cell name, parses the specified cell to get the column name.
static string GetColumnName(string? cellName)
{
    if (cellName is null)
    {
        return string.Empty;
    }

    // Create a regular expression to match the column name portion of the cell name.
    Regex regex = new Regex("[A-Za-z]+");
    Match match = regex.Match(cellName);

    return match.Value;
}

// Given a cell name, parses the specified cell to get the row index.
static uint? GetRowIndex(string? cellName)
{
    if (cellName is null)
    {
        return null;
    }

    // Create a regular expression to match the row index portion the cell name.
    Regex regex = new Regex(@"\d+");
    Match match = regex.Match(cellName);

    return uint.Parse(match.Value);
}

Confira também

Open XML SDK class library reference (Referência da biblioteca de classes SDK Open XML)