GemBox - 用于行和列的循环?

时间:2013-07-02 15:51:06

标签: c# spreadsheet gembox-spreadsheet

我有一个问题。有没有办法可以使用for循环遍历电子表格中的所有cols /行?现在我在我的代码中使用这样的foreach循环:(你可以忽略内部发生的事情)。

foreach (ExcelRow row in w1.Rows)
{
    foreach (ExcelCell cell in row.AllocatedCells)
    {

        Console.Write("row: {0}", globalVar.iRowActual);
        if (globalVar.iRowActual > 1)
        {
             cellValue = SafeCellValue(cell);
             Console.WriteLine("value is: {0}", cellValue);
        }


    }
    globalVar.iRowActual++;
}

问题在于我想将每个单元格的值分配给一个新变量并将其传递给另一个方法。我想为此使用for循环,我知道我可以使用CalculateMaxUsedColumns作为cols的限制但是有一个类似的属性,我可以用于行吗?!

这就是我想做的事情:

 int columnCount = ws.CalculateMaxUsedColumns();
 int rowCount = ws.CalculateMaxUsedRows(); ------> PART I NEED HELP WITH
 for(int i=0; i <columnCount; i++){
     for(int j = 0; j<rowCount; j++){
           .....
     }
 }

任何形式的帮助将不胜感激。感谢!!!

1 个答案:

答案 0 :(得分:4)

这是一种使用for循环遍历电子表格中所有列/行的GemBox.Spreadsheet的方法。 浏览CellRange方法返回的ExcelWorksheet.GetUsedCellRange

ExcelFile workbook = ExcelFile.Load("Sample.xlsx");
ExcelWorksheet worksheet = workbook.Worksheets[0];

CellRange range = worksheet.GetUsedCellRange(true);
for (int r = range.FirstRowIndex; r <= range.LastRowIndex; r++)
{
    for (int c = range.FirstColumnIndex; c <= range.LastColumnIndex; c++)
    {
        ExcelCell cell = range[r - range.FirstRowIndex, c - range.FirstColumnIndex];

        string cellName = CellRange.RowColumnToPosition(r, c);
        string cellRow = ExcelRowCollection.RowIndexToName(r);
        string cellColumn = ExcelColumnCollection.ColumnIndexToName(c);

        Console.WriteLine(string.Format("Cell name: {1}{0}Cell row: {2}{0}Cell column: {3}{0}Cell value: {4}{0}",
            Environment.NewLine, cellName, cellRow, cellColumn, (cell.Value) ?? "Empty"));
    }
}

修改

在较新的版本中,还有一些其他API可以简化这一过程。例如,您现在可以使用foreach并仍使用ExcelCell.Row.IndexExcelCell.Column.Index检索行索引和列索引,并且可以在不使用这些静态方法的情况下检索名称(不使用RowColumnToPositionRowIndexToNameColumnIndexToName)。

ExcelFile workbook = ExcelFile.Load("Sample.xlsx");
ExcelWorksheet worksheet = workbook.Worksheets[0];

foreach (ExcelRow row in worksheet.Rows)
{
    foreach (ExcelCell cell in row.AllocatedCells)
    {
        Console.WriteLine($"Cell value:   {cell.Value ?? "Empty"}");
        Console.WriteLine($"Cell name:    {cell.Name}");
        Console.WriteLine($"Row index:    {cell.Row.Index}");
        Console.WriteLine($"Row name:     {cell.Row.Name}");
        Console.WriteLine($"Column index: {cell.Column.Index}");
        Console.WriteLine($"Column name:  {cell.Column.Name}");
        Console.WriteLine();
    }
}

此外,还有两种方法可以在for循环中迭代表格单元格。

1)使用ExcelWorksheets.Rows.CountExcelWorksheets.CalculateMaxUsedColumns()获取上次使用的行和列。

ExcelFile workbook = ExcelFile.Load("Sample.xlsx");
ExcelWorksheet worksheet = workbook.Worksheets[0];

int rowCount = worksheet.Rows.Count;
int columnCount = worksheet.CalculateMaxUsedColumns();

for (int r = 0; r < rowCount; r++)
{
    for (int c = 0; c < columnCount; c++)
    {
        ExcelCell cell = worksheet.Cells[r, c];

        Console.WriteLine($"Cell value:  {cell.Value ?? "Empty"}");
        Console.WriteLine($"Cell name:   {cell.Name}");
        Console.WriteLine($"Row name:    {cell.Row.Name}");
        Console.WriteLine($"Column name: {cell.Column.Name}");
        Console.WriteLine();
    }
}

如果您有一个非统一的电子表格,其中行具有不同的列数(例如,第一行有10个单元格,第二行有100个单元格等),那么您可以使用以下更改以避免迭代通过未分配的单元格:

int rowCount = worksheet.Rows.Count;

for (int r = 0; r < rowCount; r++)
{
    ExcelRow row = worksheet.Rows[r];
    int columnCount = row.AllocatedCells.Count;

    for (int c = 0; c < columnCount; c++)
    {
        ExcelCell cell = row.Cells[c];

        // ...
    }
}

2)使用CellRange.GetReadEnumerator方法,它只遍历范围内已分配的单元格。

ExcelFile workbook = ExcelFile.Load("Sample.xlsx");
ExcelWorksheet worksheet = workbook.Worksheets[0];

CellRangeEnumerator enumerator = worksheet.Cells.GetReadEnumerator();
for (; enumerator.MoveNext();)
{
    ExcelCell cell = enumerator.Current;

    Console.WriteLine($"Cell value:  {cell.Value ?? "Empty"}");
    Console.WriteLine($"Cell name:   {cell.Name}");
    Console.WriteLine($"Row name:    {cell.Row.Name}");
    Console.WriteLine($"Column name: {cell.Column.Name}");
    Console.WriteLine();
}