Как я могу получить только видимые ячейки в электронной таблице Excel, используя Open XML? - PullRequest
0 голосов
/ 28 апреля 2020

Я извлекаю данные из ячеек в электронной таблице Excel, используя Open XML in C#. Я хочу получить данные, только если ячейка видна в электронной таблице. Я могу получить все ячейки с кодом ниже:

var cells = part.Worksheet.Descendants<Cell>;

Затем я могу использовать свойство CellReference.Value, чтобы выяснить, к какому столбцу принадлежит ячейка.

Приведенный ниже код даст мне видимые столбцы в электронной таблице.

var visible_columns = part.Worksheet.Descendants<Column>().Where(a => a.Hidden == null || a.Hidden.Value == false);

Я застрял, пытаясь программно связать объект ячейки с его объектом столбца. Из того, что я могу сказать, нет свойства на объекте столбца, чтобы получить его имя. В идеале я хотел бы получить имя столбца из свойства «CellReference.Value» объекта ячейки с помощью регулярного выражения. После этого я мог использовать его для получения связанного объекта столбца, который затем мог бы использовать для проверки свойства Hidden.

Я также посмотрел на свойство "Parent" объекта ячейки, но это дает мне объект Row, который не решает мою проблему. Может кто-то указать мне верное направление?

Спасибо

1 Ответ

0 голосов
/ 30 апреля 2020

Вот как вы можете прочитать ячейки, которые не находятся внутри скрытых строк или столбцов:

static void Main()
{
    using (var spreadsheetDocument = SpreadsheetDocument.Open("input.xlsx", false))
    {
        var workbookPart = spreadsheetDocument.WorkbookPart;
        var worksheetPart = workbookPart.WorksheetParts.First();
        var worksheet = worksheetPart.Worksheet;

        var columns = worksheet.Elements<Columns>().First();

        // Get names of the hidden columns.
        var hiddenColumnNames = new HashSet<string>();
        foreach (var column in columns.Elements<Column>().Where(c=> c.Hidden != null && c.Hidden.Value))
            for (uint min = column.Min, max = column.Max; min <= max; min++)
                hiddenColumnNames.Add(GetColumnName(min));

        var sheetData = worksheet.Elements<SheetData>().First();
        foreach (var row in sheetData.Elements<Row>())
        {
            // Skip cells that are in hidden row.
            if (row.Hidden != null && row.Hidden.Value)
                continue;

            foreach (var cell in row.Elements<Cell>())
            {
                // Skip cell that is in hidden column.
                var columnName = cell.CellReference.Value.Replace(row.RowIndex.ToString(), "");
                if (hiddenColumnNames.Contains(columnName))
                    continue;

                // TODO: read visible cell ...
            }
        }
    }
}

static string GetColumnName(uint columnNumber)
{
    string columnName = "";

    while (columnNumber > 0)
    {
        uint modulo = (columnNumber - 1) % 26;
        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
        columnNumber = (uint)((columnNumber - modulo) / 26);
    }

    return columnName;
}
...