Help converting a common list table <T> to Excel
I am trying to create a function that takes a generic List<T> and iterates over a list that returns an excel byte[] file. The function should be able to determine the properties of objects. Therefore, if I pass a List<person> and the person has the properties first, last, age, etc., I should be able to define property names to create excel column headings, and then I need to iterate over the list to assign property values to the cells of the column. Can someone give me some sample code for working with List<T> in a generic function?
In addition: to return columns in a known order: for members there is no specific order other than what you create. For example ( from MSDN ):
The GetProperties method does not return properties in a specific order, for example, in alphabetical order or in declaration order. Your code should not depend on the order of returning the properties, since this order is changing.
If you do not need to rely on the order, this will affect either the reflection or the TypeDescriptor; for example (noting that this writes TSV text, not byte[] ), my interpretation is that the problem is getting the data, not the Excel record):
static void WriteTsv<T>(this IEnumerable<T> data, TextWriter output) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); foreach (PropertyDescriptor prop in props) { output.Write(prop.DisplayName); // header output.Write("\t"); } output.WriteLine(); foreach (T item in data) { foreach (PropertyDescriptor prop in props) { output.Write(prop.Converter.ConvertToString( prop.GetValue(item))); output.Write("\t"); } output.WriteLine(); } } If you need an order, you need to either:
- pass it (for example, as
params string[] propertyNames) - use property attributes
- use in alphabetical order
The TypeDescriptor approach above has advantages (more GetType().GetProperties() ):
- it works with custom object models (
DataView, for example, if you useIList) - you can configure the implementation for performance - for example, HyperDescriptor (useful if you are doing these lots)
The easiest way is to convert your list to a DataTable , then convert the DataTable to an Excel spreadsheet .
The second link writes the spreadsheet directly to the ASP.NET response, this can be easily adapted to return the byte [].
Use the interface supported by your collection, for example IEnumerable :
public byte[] Process(IEnumerable input) { foreach (var elem in input) { foreach (PropertyInfo prop in elem.GetType().GetProperties()) { Object value = prop.GetValue(elem, null); // add value to byte[] } } return bytes; }