我正在寻找将IEnumerable导出到Excel 2007(.xlsb)的好方法。 T是已知类型,因此出于性能原因,反射不是完全必要的。 我使用.xlsb(excel二进制格式),因为Excel的数据量会很大。
有问题的IEnumerable有大约200万条记录。从Access数据库(.mdb)检索IEnumerable然后进行一些处理,最后写入LINQ查询以生成T的报告结构。虽然这些记录不需要作为一个发送到excel(也不是) ;它将被最大记录长度约为100万条记录的条件细分。
我希望能够将数据转换为Excel数据透视表以便于查看。
我最初的想法是将IEnumerable转换为2Darray [,]然后使用COM互操作进入Excel范围。
public static object[,] To2DArray<T>(this IEnumerable<T> objectList)
{
Type t = typeof(T);
PropertyInfo[] fields = t.GetProperties();
object[,] my2DObject = new object[objectList.Count(), fields.Count()];
int row = 0;
foreach (var o in objectList)
{
int col = 0;
foreach (var f in fields)
{
my2DObject[row, col] = f.GetValue(o, null) ?? string.Empty;
col++;
}
row++;
}
return my2DObject;
}
然后我接受了那个对象[,]并做了一个&#34;事务拆分&#34;正如我所说的那样只是将对象[,]拆分成较小的块,例如我创建一个List,然后遍历每一个并使用类似的东西发送到Excel范围:
Excel.Range range = worksheet.get_Range(cell,cell);
range.Value2 = List<object[,]>[0]
我显然循环上面但是为了简单起见,它看起来就像上面那样。 这将有效,但需要花费大量时间来处理,超过30分钟。
我已经涉足将IEnumerable输出到CSV,但它也不是很有效;因为它首先需要创建.csv文件,然后使用COM interop打开.csv文件来执行excel数据透视表格式化。
我的问题:有更好的(首选)方法吗? 我应该在迭代之前强制执行(toList())吗?
我应该使用不同的机制来输出/显示数据吗? 我打开任何选项,以有效的方式将断开的IEnumerable转换为文件。
- 我不反对使用像SQL Express这样的东西。
答案 0 :(得分:0)
主要问题是瓶颈所在。我将查看分析器中的代码,以了解执行的哪些部分需要很长时间。通过运行进程并查看CPU或内存是否短缺,或者是否已锁定磁盘,查看资源使用情况也是值得的。 如果你一次做出2000条记录的合理性能,那么我怀疑内存资源可能是一个问题 - 你发布的代码就是将IEnumerable(它可以避免将完整的数据集加载到内存中)转换成一个完整的-memory结构可能有一百万条记录 - 取决于所涉及的字段的大小和数量,这很容易成为一个问题。 如果问题看起来像创建Excel文件本身的时间(在这种情况下它不会立即听起来像),那么COM互操作调用可以加起来,并且一些第三方Excel库旨在更快在编写Excel文件时,特别是有大量记录,所以不一定要使用Excel二进制格式和COM,我建议查看像EPPlus(http://epplus.codeplex.com/)这样的开源库,看看是什么性能差异就像。