Я пытаюсь создать функцию, которая принимает общий List<T>
и повторяет список, возвращая файл excel byte[]
. Функция должна уметь определять свойства объектов. Поэтому, если я передаю List<person>
и у человека есть свойства first, last, age и т. д., мне нужно иметь возможность определить имена свойств, чтобы создать заголовки столбцов excel, а затем мне нужно повторить список, чтобы присвоить значения свойств для ячейки столбца. Может ли кто-нибудь указать мне пример кода для работы с List<T>
в универсальной функции?
Помогите преобразовать общий List‹T› в электронную таблицу Excel
Ответы (3)
Кроме того: для возврата столбцов в известном порядке: нет определенного порядка для элементов, кроме того, который вы создаете. Например (из MSDN):
Метод GetProperties не возвращает свойства в определенном порядке, например в алфавитном порядке или в порядке объявления. Ваш код не должен зависеть от порядка, в котором возвращаются свойства, потому что этот порядок может меняться.
Если вам не нужно полагаться на порядок, подойдет либо отражение, либо TypeDescriptor; например (отмечая, что это пишет текст TSV, а не byte[]
- моя интерпретация заключается в том, что проблема заключается в получении данных, а не в записи Excel):
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();
}
}
Если вам нужен заказ, вам потребуется:
- передать его (например, как
params string[] propertyNames
) - использовать атрибуты свойств
- использовать алфавитный
Описанный выше подход TypeDescriptor
имеет следующие преимущества (по сравнению с GetType().GetProperties()
):
- он работает с пользовательскими объектными моделями (например,
DataView
, если вы используетеIList
) - вы можете настроить реализацию для повышения производительности, например HyperDescriptor (полезно, если вы делаете это много)
Самый простой способ, вероятно, состоит в том, чтобы преобразовать ваш список в DataTable, затем преобразовать DataTable в электронную таблицу Excel.
Вторая ссылка записывает электронную таблицу непосредственно в ответ ASP.NET, это можно легко адаптировать для возврата byte[].
Используйте интерфейс, поддерживаемый вашей коллекцией, например 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;
}