Я отвечаю на свой вопрос.
TLTR: в текущей версии EPPlus (v4.5.1) ячейки данного диапазона всегда перечисляются в следующем порядке: сортировка по строке, затем по столбцу.
Я выяснил это, взглянув на реализацию EPPlus .
Ячейки данного листа хранятся в объекте RangeCollection
:
class ExcelWorksheet
{
RangeCollection _cells;
}
RangeCollection
содержит список ячеек.Этот список всегда сортируется по RangeID
.RangeID представляет собой комбинацию индексов строки / столбца / рабочего листа.Это позволяет EPPlus быстро находить индекс ячейки (для данной строки и столбца) путем выполнения двоичного поиска.
class RangeCollection
{
List<IRangeID> _cells;
int IndexOf(ulong rangeID)
{
return Array.BinarySearch(...);
}
}
class ExcelCell : IRangeID
{
ulong RangeID
{
get
{
return GetCellID(_worksheet.SheetID, Row, Column);
}
}
ulong GetCellID(int SheetID, int row, int col)
{
return ((ulong)SheetID) + (((ulong)col) << 15) + (((ulong)row) << 29);
}
}
При перечислении ячеек данного диапазона EPPlus будет использовать этот отсортированный список для перечисленияячейки внутри диапазона:
class ExcelRange
{
public bool MoveNext()
{
_index++;
//...
if (...)
{
GetStartIndexEnum(_fromRow, _fromCol, _toRow, _toCol);
//...
GetNextIndexEnum(_fromRow, _fromCol, _toRow, _toCol);
}
}
object IEnumerator.Current
{
get
{
return /*...*/ _worksheet._cells[_index] as ExcelCell /*...*/
}
}
}
GetStartIndexEnum()
и GetNextIndexEnum()
используются для быстрого пропуска ячеек, которые находятся за пределами диапазона, перечисленного в настоящее время.Ячейки проверяются и нумеруются в том же порядке, что и сама RangeCollection, которая всегда сортируется.