0

I have list of objects that i want to export to excel:

//My export to excel function:
public static void ExportToExcel(string[,] data, string excelFilePath = null)
{
  // .....
}

My list contains many columns so i would like to select specific columns and add them into 2d array, also add the header on the top

public class Student

{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public Address Adress { get; set; }
    public Evaluation Evaluation { get; set; }
    // ... many more
}

List:

>   IEnumerable<Student> students

Fields to be selected:

  1. Id
  2. Name
  3. Address.Zipcode

I can perform this with for loop however i'm interested in linq, also i would like to hear your advice about performance since the list has + 200k records

Edit Sample

Columns => ID Name Zipcode

Rows => values

ID Name Zip
1  Mike 1101 
2  Jan  2250
3  Peter 4456
Maro
  • 2,579
  • 9
  • 42
  • 79
  • Why do you want to use 2d array for it and not some DTO? From where you get this data? – Konstantin Ershov Sep 13 '16 at 09:41
  • Something like `students.Select(i => new { i.Id, i.Name, i.Address.Zipcode }).ToArray()` and save it to whatever array you want. Actually I am unsure of why you need a 2d array instead of 1d? – Keyur PATEL Sep 13 '16 at 09:42
  • What are the two dimensions of your array? Can you show a sample declaration of the array you expect? – Matthew Watson Sep 13 '16 at 09:48
  • 1
    If you are concerned about performance then `ExportToExcel()` should expect an `IEnumerable` instead of a `string[,]`. This way you can export item by item and line by line without ever having all the +200k records in memory at the same time. – Good Night Nerd Pride Sep 13 '16 at 09:53
  • Sample added in the post – Maro Sep 13 '16 at 09:59

4 Answers4

2

You could deal with Jagged Arrays and do something like this, there is no direct way of creating multi dimensional array with in Linq (At least that I'm aware), so try using Array of Arrays.

var result = students.Select(x=> new string[] 
                                 {
                                      x.Id.ToString(), 
                                      x.Name, 
                                      x.Address.ZipCode
                                 })
                     .ToArray();

Still keen and not interested in changing function definition? Well, you could use this logic to convert result to Multi dimensional array.

Community
  • 1
  • 1
Hari Prasad
  • 16,716
  • 4
  • 21
  • 35
2

I think I understand why you need the 2d array. I ran into the same issue when exporting hundreds of records using linq and interop.Excel

Here is a brief overview of what I did:

var list = students.Select(i => new { i.Id, i.Name, i.Address.Zipcode }).ToList();
int i=0;
foreach (var stud in list)
{
    data[i, 0] = stud.Id;
    data[i, 1] = stud.Name;
    data[i, 2] = stud.Address.Zipcode;
    i++;
}

Then use the data array to convert into excel range by using Excel.Range.set_Value. In my code, I used a 2d array of objects instead of strings since set_Value only accepts array of objects.

testRng.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, data);

where testRng is an Excel.Range

Keyur PATEL
  • 2,299
  • 1
  • 15
  • 41
0

You can create another class with just the columns you want, say LiteStudent

Then use something like this.

students.select(x => new LiteStudent{
 Id = x.Id,
 Name = x.Name,
 ZipCode = x.Address.ZipCode
}).ToArray();

Or creating no new class at all

students.select(x => new {
 Id = x.Id,
 Name = x.Name,
 ZipCode = x.Address.ZipCode
}).ToArray();

Edit: If you want to convert to a 2D string array, follow the answer by Hari Prasad.

As for performance, you may want to take a look at this answer, it might be possible to use multi-threading to speed up processing of large data somehow.

If not limited to Linq, we can divide the list into smaller lists and create multiple threads to assign data in parallel, each thread process a part of the list.

Community
  • 1
  • 1
0

You can do something like this

class YourNewStuff
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Zip { get; set; }
}

var newstuff2 = new List<YourNewStuff>();

students.Select(x => newstuff2.Add(new YourNewStuff()
{
    Id = x.Id,
    Name = x.Name,
    Zip = x.Adress.Zip
});
Jens Hunt
  • 36
  • 4