Mat*_*att 4 .net c# excel list generic-list
使用C#,有没有直接的方法将列表列表(即List<List<T>>)导出到Excel 2003?
我正在解析大文本文件并导出到Excel.一次写一个单元格会产生太多的开销.我选择使用,List<T>以便我不必担心指定行数或列数.
目前,我等到文件结束,然后把我的内容List<List<object>>放到一个二维数组中.然后可以将数组设置为Excel.Range对象的值.它可以工作,但似乎我应该能够获取列表列表,而不必担心行或列的数量,只需将其转储到从A1到任何地方的工作表中.
这是我要替换或改进的代码片段:
object oOpt = System.Reflection.Missing.Value; //for optional arguments
Excel.Application oXL = new Excel.Application();
Excel.Workbooks oWBs = oXL.Workbooks;
Excel._Workbook oWB = oWBs.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel._Worksheet oSheet = (Excel._Worksheet)oWB.ActiveSheet;
int numberOfRows = outputRows.Count;
int numberOfColumns = int.MinValue;
//outputRows is a List<List<object>>
foreach (List<object> outputColumns in outputRows)
{
if (numberOfColumns < outputColumns.Count)
{ numberOfColumns = outputColumns.Count; }
}
Excel.Range oRng = oSheet.get_Range("A1", oSheet.Cells[numberOfRows,numberOfColumns]);
object[,] outputArray = new object[numberOfRows,numberOfColumns];
for (int row = 0; row < numberOfRows; row++)
{
for (int col = 0; col < outputRows[row].Count; col++)
{
outputArray[row, col] = outputRows[row][col];
}
}
oRng.set_Value(oOpt, outputArray);
oXL.Visible = true;
oXL.UserControl = true;
Run Code Online (Sandbox Code Playgroud)
这是有效的,但我宁愿直接使用List到Excel,而不是为了Excel而创建数组的中间步骤.有任何想法吗?
Mik*_*lum 10
从战略上讲,你正确地做到了.正如Joe所说,通过一次性传递整个数组值而不是逐个循环遍历单元格,执行单元格值分配的速度要快得多.
Excel是基于COM的,因此通过.NET互操作与Excel一起运行.不幸的是,互操作不知道泛型,所以你不能将它传递给List <T>等.二维阵列确实是唯一的出路.
也就是说,有几种方法可以清理代码,使其更易于管理.以下是一些想法:
(1)如果您使用的是.NET 3.0,则可以使用LINQ缩短代码:
int numberOfColumns = int.MinValue;
foreach (List<object> outputColumns in outputRows)
{
if (numberOfColumns < outputColumns.Count)
{ numberOfColumns = outputColumns.Count; }
}
Run Code Online (Sandbox Code Playgroud)
到一行:
int numberOfColumns = outputRows.Max(list => list.Count);
Run Code Online (Sandbox Code Playgroud)
(2)不要使用_Worksheet或_Workbook接口.利用Worksheet或Workbook代替.请参阅此处讨论:Excel互操作:_Worksheet或工作表?.
(3)考虑利用所述的Range.Resize方法,该方法通过附带如Range.get_Resize在C#.这是一个折腾 - 我实际上喜欢你设置范围大小的方式.但这是我认为你可能想知道的事情.例如,您的行在这里:
Excel.Range oRng = oSheet.get_Range("A1", oSheet.Cells[numberOfRows,numberOfColumns]);
Run Code Online (Sandbox Code Playgroud)
可以改为:
Excel.Range oRng =
oSheet.get_Range("A1", Type.Missing)
.get_Resize(numberOfRows, numberOfColumns);
Run Code Online (Sandbox Code Playgroud)
(4)您不必设置Application.UserControl为true.使Excel对用户可见就足够了.该UserControl物业没有按照您的想法行事.(请参阅此处的帮助文件)如果要控制用户是否可以控制Excel,则应使用工作表保护,或者可以设置Application.Interactive = false是否要锁定用户.(很少有好主意.)但是如果你想让用户使用Excel,那么只需让它可见即可.
总的来说,考虑到这些,我认为您的代码看起来像这样:
object oOpt = System.Reflection.Missing.Value; //for optional arguments
Excel.Application oXL = new Excel.Application();
Excel.Workbooks oWBs = oXL.Workbooks;
Excel.Workbook oWB = oWBs.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet oSheet = (Excel.Worksheet)oWB.ActiveSheet;
//outputRows is a List<List<object>>
int numberOfRows = outputRows.Count;
int numberOfColumns = outputRows.Max(list => list.Count);
Excel.Range oRng =
oSheet.get_Range("A1", oOpt)
.get_Resize(numberOfRows, numberOfColumns);
object[,] outputArray = new object[numberOfRows, numberOfColumns];
for (int row = 0; row < numberOfRows; row++)
{
for (int col = 0; col < outputRows[row].Count; col++)
{
outputArray[row, col] = outputRows[row][col];
}
}
oRng.set_Value(oOpt, outputArray);
oXL.Visible = true;
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助...
麦克风