如何以及何时使用枚举器

如何使用枚举器

单元格枚举器

有各种方式可以访问单元格枚举器,并且可以根据应用程序的要求使用任何这些方法。以下是返回单元格枚举器的方法。

  1. Cells.GetEnumerator
  2. Row.GetEnumerator
  3. Range.GetEnumerator

上述所有方法都返回允许遍历初始化的单元格集合的枚举器。

以下代码示例演示了为Cells集合实现IEnumerator接口。

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// Load a file in an instance of Workbook
var book = new Workbook(dataDir + "sample.xlsx");
// Get the enumerator from Cells collection
IEnumerator cellEnumerator = book.Worksheets[0].Cells.GetEnumerator();
// Traverse cells in the collection
while (cellEnumerator.MoveNext())
{
var cell = cellEnumerator.Current as Aspose.Cells.Cell;
Console.WriteLine(cell.Name + " " + cell.Value);
}
// Get enumerator from an object of Row
IEnumerator rowEnumerator = book.Worksheets[0].Cells.Rows[0].GetEnumerator();
// Traverse cells in the given row
while (rowEnumerator.MoveNext())
{
var cell = rowEnumerator.Current as Aspose.Cells.Cell;
Console.WriteLine(cell.Name + " " + cell.Value);
}
// Get enumerator from an object of Range
IEnumerator rangeEnumerator = book.Worksheets[0].Cells.CreateRange("A1:B10").GetEnumerator();
// Traverse cells in the range
while (rangeEnumerator.MoveNext())
{
var cell = rangeEnumerator.Current as Aspose.Cells.Cell;
Console.WriteLine(cell.Name + " " + cell.Value);
}

行枚举器

RowCollection.GetEnumerator方法中可以访问行枚举器。以下代码示例演示了为RowCollection实现IEnumerator接口。

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET
// Load a file in an instance of Workbook
var book = new Workbook(dataDir + "sample.xlsx");
// Get the enumerator for RowCollection
IEnumerator rowsEnumerator = book.Worksheets[0].Cells.Rows.GetEnumerator();
// Traverse rows in the collection
while (rowsEnumerator.MoveNext())
{
var row = rowsEnumerator.Current as Aspose.Cells.Row;
Console.WriteLine(row.Index);
}

列枚举器

ColumnCollection.GetEnumerator方法中可以访问列枚举器。以下代码示例演示了为ColumnCollection实现IEnumerator接口。

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET
// Load a file in an instance of Workbook
var book = new Workbook(dataDir + "sample.xlsx");
// Get the enumerator for ColumnsCollection
IEnumerator colsEnumerator = book.Worksheets[0].Cells.Columns.GetEnumerator();
// Traverse columns in the collection
while (colsEnumerator.MoveNext())
{
var col = colsEnumerator.Current as Aspose.Cells.Column;
Console.WriteLine(col.Index);
}

枚举器的使用场景

为了讨论使用枚举器的优势,让我们举一个实时例子。

情景

一个应用程序要求是遍历给定的Worksheet中的所有单元格以读取它们的值。有几种实现此目标的方法。以下是一些示例。

使用显示范围

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET
// Load a file in an instance of Workbook
var book = new Workbook(dataDir + "sample.xlsx");
// Get Cells collection of first worksheet
var cells = book.Worksheets[0].Cells;
// Get the MaxDisplayRange
var displayRange = cells.MaxDisplayRange;
// Loop over all cells in the MaxDisplayRange
for (int row = displayRange.FirstRow; row < displayRange.RowCount; row++)
{
for (int col = displayRange.FirstColumn; col < displayRange.ColumnCount; col++)
{
// Read the Cell value
Console.WriteLine(displayRange[row, col].StringValue);
}
}

使用MaxDataRow和MaxDataColumn

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET
// Load a file in an instance of Workbook
var book = new Workbook(dataDir + "sample.xlsx");
// Get Cells collection of first worksheet
var cells2 = book.Worksheets[0].Cells;
int maxDataRow = cells2.MaxDataRow;
int maxDataColumn = cells2.MaxDataColumn;
// Loop over all cells
for (int row = 0; row <= maxDataRow; row++)
{
for (int col = 0; col <= maxDataColumn; col++)
{
// Read the Cell value
var currentCell = cells2.CheckCell(row, col);
if (currentCell != null)
{
Console.WriteLine(currentCell.StringValue);
}
}
}

正如您所注意到的,上述两种方法都使用了几乎相似的逻辑,即在集合中循环遍历所有单元格以读取单元格的值。对于许多原因,这可能会有问题,如下所讨论的。

  1. 诸如MaxRowMaxDataRowMaxColumnMaxDataColumnMaxDisplayRange之类的API需要额外的时间来收集相应的统计信息。如果数据矩阵(行x列)很大,在使用这些API时可能会导致性能损失。
  2. 在大多数情况下,给定范围中并非所有单元格都被实例化。在这种情况下,检查矩阵中的每个单元格比仅检查初始化的单元格效率低。
  3. 在循环中访问单元格作为Cells row, column将导致范围内的所有单元格对象被实例化,这最终可能导致OutOfMemoryException。

结论

基于上述事实,以下是应该使用枚举器的可能情况。

  1. 需要只读访问单元格集合,即只需检查单元格。
  2. 需要遍历大量的单元格。
  3. 只需遍历已初始化的单元格/行/列。