Универсальный класс к CSV (все свойства)

Я ищу способ создать CSV из всех экземпляров класса.

То, что я хочу, - то, что я мог экспортировать ЛЮБОЙ класс (все его экземпляры) к CSV.

Уже может some1 прямой меня к возможному решению для этого (в случае, если anwsered).

Спасибо!

15
задан no9 29 July 2010 в 12:07
поделиться

3 ответа

На самом деле, нечто подобное было рассмотрено здесь:

Рекомендации по сериализации объектов в настраиваемый строковый формат для использования в выходном файле

Полезно ли это для вас?

Существует образец, в котором используется отражение чтобы вытащить имена и значения полей и добавить их в строку.

9
ответ дан 1 December 2019 в 03:34
поделиться

Вы можете использовать отражение , чтобы просмотреть все свойства / поля класса и записать их в CSV. Лучшим подходом было бы определить настраиваемый атрибут и украсить элементы, которые вы хотите экспортировать, и экспортировать только эти атрибуты.

1
ответ дан 1 December 2019 в 03:34
поделиться

Посмотрите LINQ to CSV . Хотя это немного тяжеловато, поэтому я написал следующий код для выполнения лишь небольшого подмножества необходимых мне функций. Он обрабатывает как свойства, так и поля, как вы просили, но не более того. Одна вещь, которую он делает, - это правильно экранировать вывод, если он содержит запятые, кавычки или символы новой строки.

public static class CsvSerializer {
    /// <summary>
    /// Serialize objects to Comma Separated Value (CSV) format [1].
    /// 
    /// Rather than try to serialize arbitrarily complex types with this
    /// function, it is better, given type A, to specify a new type, A'.
    /// Have the constructor of A' accept an object of type A, then assign
    /// the relevant values to appropriately named fields or properties on
    /// the A' object.
    /// 
    /// [1] http://tools.ietf.org/html/rfc4180
    /// </summary>
    public static void Serialize<T>(TextWriter output, IEnumerable<T> objects) {
        var fields =
            from mi in typeof (T).GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
            where new [] { MemberTypes.Field, MemberTypes.Property }.Contains(mi.MemberType)
            let orderAttr = (ColumnOrderAttribute) Attribute.GetCustomAttribute(mi, typeof (ColumnOrderAttribute))
            orderby orderAttr == null ? int.MaxValue : orderAttr.Order, mi.Name
            select mi;
        output.WriteLine(QuoteRecord(fields.Select(f => f.Name)));
        foreach (var record in objects) {
            output.WriteLine(QuoteRecord(FormatObject(fields, record)));
        }
    }

    static IEnumerable<string> FormatObject<T>(IEnumerable<MemberInfo> fields, T record) {
        foreach (var field in fields) {
            if (field is FieldInfo) {
                var fi = (FieldInfo) field;
                yield return Convert.ToString(fi.GetValue(record));
            } else if (field is PropertyInfo) {
                var pi = (PropertyInfo) field;
                yield return Convert.ToString(pi.GetValue(record, null));
            } else {
                throw new Exception("Unhandled case.");
            }
        }
    }

    const string CsvSeparator = ",";

    static string QuoteRecord(IEnumerable<string> record) {
        return String.Join(CsvSeparator, record.Select(field => QuoteField(field)).ToArray());
    }

    static string QuoteField(string field) {
        if (String.IsNullOrEmpty(field)) {
            return "\"\"";
        } else if (field.Contains(CsvSeparator) || field.Contains("\"") || field.Contains("\r") || field.Contains("\n")) {
            return String.Format("\"{0}\"", field.Replace("\"", "\"\""));
        } else {
            return field;
        }
    }

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
    public class ColumnOrderAttribute : Attribute {
        public int Order { get; private set; }
        public ColumnOrderAttribute(int order) { Order = order; }
    }
}
10
ответ дан 1 December 2019 в 03:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: