Epplus不支持usedrange,但是你可以使用usedrange.cs来实现。
假设你已经下载了最新的EPPlus源代码,
对Worksheet.cs进行更改:将原始文件partial化。
然后创建一个名为UsedRange.cs的单独cs文件,将下面的代码粘贴到其中并编译。
namespace OfficeOpenXml
{
using System;
using System.Collections.Generic;
using System.Text;
using OfficeOpenXml.Style;
using System.Data;
public sealed class UsedRange : ExcelRange,IEnumerable<UsedRange>
{
#region local variables
int elementIndex=-1, cursor=-1, position=-1;
UsedRangeElement element, parentElement;
public const long MaxCells =(long) ExcelPackage.MaxRows *
(long)ExcelPackage.MaxColumns;
#endregion
#region constructors
UsedRange(ExcelWorksheet sheet, UsedRangeElement element, int elementIndex, int cursor)
: base(sheet)
{
this.element = element;
switch (element)
{
case UsedRangeElement.Rows:
case UsedRangeElement.Columns:
case UsedRangeElement.Cells:
parentElement = UsedRangeElement.Range;
break;
case UsedRangeElement.Row:
parentElement = UsedRangeElement.Rows;
break;
case UsedRangeElement.Column:
parentElement = UsedRangeElement.Columns;
break;
case UsedRangeElement.Cell:
parentElement = UsedRangeElement.Cells;
break;
case UsedRangeElement.RowCell:
parentElement = UsedRangeElement.Row;
break;
case UsedRangeElement.ColumnCell:
parentElement = UsedRangeElement.Column;
break;
default:
parentElement = 0;
break;
}
this.elementIndex = elementIndex;
this.cursor = cursor;
SetRange();
}
UsedRange(ExcelWorksheet sheet, UsedRangeElement element, int elementIndex)
: this(sheet, element, elementIndex, -1) { }
UsedRange(ExcelWorksheet sheet, UsedRangeElement element)
: this(sheet, element, -1, -1) { }
UsedRange(ExcelWorksheet sheet, long cellIndex)
: base(sheet)
{
this.element = UsedRangeElement.Cell;
this.parentElement = UsedRangeElement.Cells;
CellToAddress(cellIndex);
SetRange();
}
#endregion
#region indexers & properties
public UsedRange this[int index]
{
get
{
if (index >= Count || index < 0) throw new IndexOutOfRangeException();
switch (element)
{
case UsedRangeElement.Rows:
ValidateRow(index);
return new UsedRange(_worksheet, UsedRangeElement.Row, index);
case UsedRangeElement.Columns:
ValidateCol(index);
return new UsedRange(_worksheet, UsedRangeElement.Column, index);
case UsedRangeElement.Cells:
ValidateCell(index);
return new UsedRange(_worksheet, index);
case UsedRangeElement.Row:
return new UsedRange(_worksheet, UsedRangeElement.RowCell, elementIndex, index);
case UsedRangeElement.Column:
return new UsedRange(_worksheet, UsedRangeElement.ColumnCell, elementIndex, index);
default:
return this;
}
}
}
public UsedRange this[long index]
{
get
{
ValidateCell(index);
return new UsedRange(_worksheet, index);
}
}
public int Count
{
get
{
switch (element)
{
case UsedRangeElement.Rows:
case UsedRangeElement.Column:
return _toRow - _fromRow + 1;
case UsedRangeElement.Columns:
case UsedRangeElement.Row:
return _toCol - _fromCol + 1;
case UsedRangeElement.Cells:
case UsedRangeElement.Range:
return (_toRow - _fromRow + 1) * (_toCol - _fromCol + 1);
default:
return 1;
}
}
}
public UsedRangeElement Element
{
get { return element; }
}
public UsedRangeElement ParentElement
{
get { return parentElement; }
}
#endregion
#region private methods
private void ValidateRow(int Row)
{
if (Row < 0 || Row > ExcelPackage.MaxRows)
{
throw (new ArgumentException("Row out of range"));
}
}
private void ValidateCol(int Col)
{
if (Col < 0 || Col > ExcelPackage.MaxColumns)
{
throw (new ArgumentException("Column out of range"));
}
}
private void ValidateCell(long Cell)
{
if (Cell <0 || Cell > UsedRange.MaxCells)
{
throw (new ArgumentException("Cell out of range"));
}
}
private void CellToAddress(long Cell)
{
long rc = ((_worksheet._cells[_worksheet._cells.Count - 1] as ExcelCell).Row
- (_worksheet._cells[0] as ExcelCell).Row) + 1;
long cc = _worksheet._maxCol - _worksheet._minCol + 1;
elementIndex = (int)(Cell / cc) + 1;
cursor = (int)(Cell % cc) + 1;
}
ExcelRange SetRange()
{
switch (element)
{
case UsedRangeElement.Rows:
case UsedRangeElement.Columns:
case UsedRangeElement.Cells:
return this[(_worksheet._cells[0] as ExcelCell).Row, _worksheet._minCol,
(this._worksheet._cells[_worksheet._cells.Count - 1] as ExcelCell).Row,
_worksheet._maxCol];
case UsedRangeElement.Row:
return this[elementIndex + 1, _worksheet._minCol, elementIndex + 1, _worksheet._maxCol];
case UsedRangeElement.Column:
return this[(_worksheet._cells[0] as ExcelCell).Row, elementIndex + 1,
(_worksheet._cells[_worksheet._cells.Count - 1] as ExcelCell).Row, elementIndex + 1];
case UsedRangeElement.RowCell:
case UsedRangeElement.Cell:
return this[elementIndex + 1, cursor + 1];
case UsedRangeElement.ColumnCell:
return this[cursor + 1, elementIndex + 1];
default:
return this;
}
}
#endregion
#region internal static methods
internal static UsedRange RowCollection(ExcelWorksheet sheet)
{
return new UsedRange(sheet, UsedRangeElement.Rows);
}
internal static UsedRange ColumnCollection(ExcelWorksheet sheet)
{
return new UsedRange(sheet, UsedRangeElement.Columns);
}
internal static UsedRange CellCollection(ExcelWorksheet sheet)
{
return new UsedRange(sheet, UsedRangeElement.Cells);
}
#endregion
#region ienumerable implementation
public new IEnumerator<UsedRange> GetEnumerator()
{
position = -1;
for (int i = 0; i < Count; i++)
{
++position;
yield return this[i];
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
public enum UsedRangeElement
{
Range, Rows, Columns, Cells,
Row, Column, Cell, RowCell, ColumnCell
}
}
public sealed partial class ExcelWorksheet : XmlHelper
{
public UsedRange UsedRows
{
get
{
return UsedRange.RowCollection(this);
}
}
public UsedRange UsedColumns
{
get
{
return UsedRange.ColumnCollection(this);
}
}
public UsedRange UsedCells
{
get
{
return UsedRange.CellCollection(this);
}
}
}
}
string.IsNullOrEmpty(workSheet.Cells[i, 1].Text)
。 - Petr Tomášek