如何仅使用OpenXML在Excel电子表格中获得可见的单元格?

问题描述 投票:0回答:1

我正在使用C#中的OpenXML从Excel电子表格的单元格中提取数据。我只想在单元格在电子表格上可见的情况下提取数据。我可以使用以下代码获取所有单元格:

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对象,它不能解决我的问题。谁能指出我正确的方向?

谢谢

c# excel openxml
1个回答
0
投票

这里是您如何读取不在隐藏的行或列内的单元格的方法:

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.