我有一个输出Excel范围为object[,]
的方法:
static public Excel.Workbook OpenWorksheetAsReadOnly(string filePath)
{
Excel.Application excelInstance = null;
// Open workbook as readOnly, update links
excelInstance = new Excel.Application();
Excel.Workbook excelWorkbook = excelInstance.Workbooks.
Open(filePath, true, true);
return excelWorkbook;
}
static public object[,] ImportExcelIntoArray(string filePath)
{
Excel.Workbook source = null;
source = OpenWorksheetAsReadOnly(filePath);
Excel.Range sourceRange = source.Sheets[1].Range("B1:D1000");
object[,] sourceValues = (object[,])sourceRange.Value2;
return sourceValues;
}
我知道我的输出数组是1000行。我也知道并非所有这些行都会被填充,而且我知道源文档是从上到下填充的。
在另一种方法中,我想迭代行,但为了节省时间,我只想迭代实际填充行的数量。理想情况下,我会使用(其中excelObject
是上述方法的输出):
int rowCount = excelObject.Count(x => x != null);
但是,它不适用于object[*,*]
类型 - 我认为它适用于List
。我看过这里,我看过excelObject.Length
,但这只是给了我对象中单元格的数量。
有没有办法做到这一点?我是否需要将类型从object
更改为其他内容?单元格中的值既是字符串又是浮点数,所以我希望尽可能长时间地保留它,而不是类型指定。
答案 0 :(得分:4)
由于2d数组实现了非通用IEnumerable
接口,您可以使用Enumerable.Cast<T>
扩展方法将其转换为IEnumerable<T>
,然后在其上应用所需的LINQ运算符:< / p>
int rowCount = excelObject.Cast<object>().Count(x => x != null);
但请注意,上面实际上计算非空单元格。如果您真的想要计算非空的行,可以使用Enumerable.Range
在源数组中生成行/列索引:
var rowCount = Enumerable.Range(0, excelObject.GetLength(0))
.Count(row => Enumerable.Range(0, excelObject.GetLength(1))
.Any(col => excelObject[row, col] != null));