Export a C# List of Lists to Excel

后端 未结 4 864
深忆病人
深忆病人 2021-01-03 07:05

Using C#, is there a direct way to export a List of Lists (i.e., List>) to Excel 2003?

I am parsing out large text files and exporti

相关标签:
4条回答
  • 2021-01-03 07:54
    List<"classname"> getreport = cs.getcompletionreport();
    
    var getreported = getreport .Select(c => new { demographic = c.rName);
    

    hopes this helps

    where cs.getcompletionreport() is reference class file is Business Layer for App

    0 讨论(0)
  • 2021-01-03 07:55

    It's much faster to pass a two-dimensional array to Excel than to update cells one at a time.

    Create a 2-dimensional array of objects with values from your list of lists, redimension the Excel range to the dimensions of your array, and then call range.set_Value, passing your two-dimensional array.

    0 讨论(0)
  • 2021-01-03 07:55

    For future searchers: It is true that if you want to copy list to excel you have to paste object[,] (2 dimensional). Just in case someone has one dimensional list you can run just one for loop with second dimesion 1:

    List<DateTime> listDate; //I'm filling it with data from datagridview
    ...
    object[,] outDate = new object[listDate.Count, 1];
    for(int row = 0; row < listDate.Count; row++)
    {
        outDate[row, 0] = listDate[row];
    }
    
    0 讨论(0)
  • 2021-01-03 08:00

    Strategically, you are doing it correctly. As Joe says, it is massively faster to execute cell value assignments by passing an entire array of values in one shot rather than by looping through the cells one by one.

    Excel is COM based and so operates with Excel via the .NET interop. The interop is ignorant of generics, unfortunately, so you cannot pass it a List<T> or the like. A two dimensional array really is the only way to go.

    That said, there are a few ways to clean up your code to make it a bit more manageable. Here are some thoughts:

    (1) If you are using .NET 3.0, you can use LINQ to shorten your code from:

    int numberOfColumns = int.MinValue;
    
    foreach (List<object> outputColumns in outputRows)
    {
            if (numberOfColumns < outputColumns.Count)
            { numberOfColumns = outputColumns.Count; }
    }
    

    to a single line:

    int numberOfColumns = outputRows.Max(list => list.Count);
    

    (2) Don't use the _Worksheet or _Workbook interfaces. Make use of Worksheet or Workbook instead. See here for a discussion: Excel interop: _Worksheet or Worksheet?.

    (3) Consider making use of the Range.Resize method, which comes through as Range.get_Resize in C#. This is a toss-up though -- I actually like the way you are setting your range size. But it's something that I thought that you might want to know about. For example, your line here:

    Excel.Range oRng = oSheet.get_Range("A1", oSheet.Cells[numberOfRows,numberOfColumns]);
    

    Could be changed to:

    Excel.Range oRng = 
        oSheet.get_Range("A1", Type.Missing)
            .get_Resize(numberOfRows, numberOfColumns);
    

    (4) You do not have to set the Application.UserControl to true. Making Excel visible to the user is enough. The UserControl property is not doing what you think it does. (See the help files here) If you want to control whether the user can control Excel or not, you should utilze Worksheet protection, or you could set Application.Interactive = false if you want to lock out your users. (Rarely a good idea.) But if you want to allow the user to use Excel, then simply making it visible is enough.

    Overall, with these in mind, I think that your code could look something like this:

    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;
    

    Hope this helps...

    Mike

    0 讨论(0)
提交回复
热议问题