Compartilhar via


Obter uma lista das linhas ou colunas ocultas num documento de folha de cálculo

Este tópico mostra como utilizar as classes no SDK Open XML para o Office para obter programaticamente uma lista de linhas ou colunas ocultas numa folha de cálculo do Microsoft Excel. Contém um método de exemplo GetHiddenRowsOrCols para ilustrar esta tarefa.


Método GetHiddenRowsOrCols

Pode utilizar o GetHiddenRowsOrCols método para obter uma lista das linhas ou colunas ocultas numa folha de cálculo. O método devolve uma lista de números inteiros não assinados que contêm cada índice para as linhas ou colunas ocultas, se a folha de cálculo especificada contiver linhas ou colunas ocultas (as linhas e colunas são numeradas a partir de 1, em vez de 0). O método GetHiddenRowsOrCols aceita três parâmetros:

  • O nome do documento a examinar (cadeia).

  • O nome da folha a examinar (cadeia).

  • Se pretende detetar linhas (verdadeiro) ou colunas (falso) (Booleano).


Como Funciona o Código

O código abre o documento com o <método DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open*> e indica que o documento deve estar aberto para acesso só de leitura (o valor final false do parâmetro). Em seguida, o código obtém uma referência à peça do livro, utilizando a WorkbookPart propriedade do documento.

using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false))
{
    if (document is not null)
    {
        WorkbookPart wbPart = document.WorkbookPart ?? document.AddWorkbookPart();

Para localizar as linhas ou colunas ocultas, o código tem primeiro de obter uma referência para a folha especificada, dado o respetivo nome. Isto não é tão fácil como possas pensar. O código tem de analisar todos os descendentes do tipo folha da propriedade da peça do Workbook livro, examinando a Name propriedade de cada folha que encontrar. Tenha em atenção que esta pesquisa simplesmente analisa as relações do livro e não encontra realmente uma parte da folha de cálculo. Localiza simplesmente uma referência a um Sheet objeto, que contém informações como o nome e Id a propriedade da folha. A forma mais simples de o fazer é utilizar uma consulta LINQ.

Sheet? theSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault((s) => s.Name == sheetName);

As informações da folha que já obteve fornecem uma Id propriedade e, tendo em conta essa Id propriedade, o código pode obter uma referência à propriedade correspondente WorksheetPart ao chamar o GetPartById método do WorkbookPart objeto.

// The sheet does exist.
WorksheetPart? wsPart = wbPart.GetPartById(theSheet.Id!) as WorksheetPart;
Worksheet? ws = wsPart?.Worksheet;

Obter a Lista de Valores de Índice de Linhas ou Colunas Ocultas

O código utiliza o detectRows parâmetro que especificou quando chamou o método para determinar se pretende obter informações sobre linhas ou colunas. O código que realmente obtém a lista de linhas ocultas requer apenas uma única linha de código.

// Retrieve hidden rows.
itemList = ws.Descendants<Row>()
    .Where((r) => r?.Hidden is not null && r.Hidden.Value)
    .Select(r => r.RowIndex?.Value)
    .Cast<uint>()
    .ToList();

Obter a lista de colunas ocultas é um pouco mais complicado, porque o Excel fecha grupos de colunas ocultas num único elemento e fornece propriedades Min que Max descrevem a primeira e a última coluna no grupo. Por conseguinte, o código que obtém a lista de colunas ocultas começa da mesma forma que o código que obtém linhas ocultas. No entanto, tem de iterar através dos valores de índice (repetindo cada item na coleção de colunas ocultas, adicionando cada índice do Min ao Max valor, inclusive).

var cols = ws.Descendants<Column>().Where((c) => c?.Hidden is not null && c.Hidden.Value);

foreach (Column item in cols)
{
    if (item.Min is not null && item.Max is not null)
    {
        for (uint i = item.Min.Value; i <= item.Max.Value; i++)
        {
            itemList.Add(i);
        }
    }
}

Código de exemplo

Segue-se o exemplo de código completo GetHiddenRowsOrCols em C# e Visual Basic.

static List<uint> GetHiddenRowsOrCols(string fileName, string sheetName, string detectRows = "false")
{
    // Given a workbook and a worksheet name, return 
    // either a list of hidden row numbers, or a list 
    // of hidden column numbers. If detectRows is true, return
    // hidden rows. If detectRows is false, return hidden columns. 
    // Rows and columns are numbered starting with 1.
    List<uint> itemList = new List<uint>();

    using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false))
    {
        if (document is not null)
        {
            WorkbookPart wbPart = document.WorkbookPart ?? document.AddWorkbookPart();

            Sheet? theSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault((s) => s.Name == sheetName);

            if (theSheet is null || theSheet.Id is null)
            {
                throw new ArgumentException("sheetName");
            }
            else
            {

                // The sheet does exist.
                WorksheetPart? wsPart = wbPart.GetPartById(theSheet.Id!) as WorksheetPart;
                Worksheet? ws = wsPart?.Worksheet;

                if (ws is not null)
                {
                    if (detectRows.ToLower() == "true")
                    {
                        // Retrieve hidden rows.
                        itemList = ws.Descendants<Row>()
                            .Where((r) => r?.Hidden is not null && r.Hidden.Value)
                            .Select(r => r.RowIndex?.Value)
                            .Cast<uint>()
                            .ToList();
                    }
                    else
                    {
                        // Retrieve hidden columns.
                        var cols = ws.Descendants<Column>().Where((c) => c?.Hidden is not null && c.Hidden.Value);

                        foreach (Column item in cols)
                        {
                            if (item.Min is not null && item.Max is not null)
                            {
                                for (uint i = item.Min.Value; i <= item.Max.Value; i++)
                                {
                                    itemList.Add(i);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return itemList;
}

Confira também