Generic class to CSV (all properties)

前端 未结 5 1181
梦如初夏
梦如初夏 2021-02-13 02:42

Im looking for a way to create CSV from all class instances.

What i want is that i could export ANY class (all of its instances) to CSV.

Can some1 direct me to p

5条回答
  •  一向
    一向 (楼主)
    2021-02-13 03:21

    Have a look at LINQ to CSV. Although it's a little on the heavy side, which is why I wrote the following code to perform just the small subset of functionality that I needed. It handles both properties and fields, like you asked for, although not much else. One thing it does do is properly escape the output in case it contains commas, quotes, or newline characters.

    public static class CsvSerializer {
        /// 
        /// 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
        /// 
        public static void Serialize(TextWriter output, IEnumerable 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 FormatObject(IEnumerable 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 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; }
        }
    }
    

提交回复
热议问题