Generic class to CSV (all properties)

前端 未结 5 1179
梦如初夏
梦如初夏 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:20

    I am separating my answer into two sections: The first one is how to export some generic item list into csv, with encoding, headers - (it will build csv data only for specified headers, and will ignore unneeded properties).

    public string ExportCsv(IEnumerable items, Dictionary headers)
    {
        string result;
        using (TextWriter textWriter = new StreamWriter(myStream, myEncoding))
        {
            result = this.WriteDataAsCsvWriter(items, textWriter, headers);
        }
        return result;
    }
    
    private string WriteDataAsCsvWriter(IEnumerable items, TextWriter textWriter, Dictionary headers)
    {
        //Add null validation
    
        ////print the columns headers
        StringBuilder sb = new StringBuilder();
    
        //Headers
        foreach (KeyValuePair kvp in headers)
        {
            sb.Append(ToCsv(kvp.Value));
            sb.Append(",");
        }
        sb.Remove(sb.Length - 1, 1);//the last ','
        sb.Append(Environment.NewLine);
    
        //the values
        foreach (var item in items)
        {
            try
            {
                Dictionary values = GetPropertiesValues(item, headers);
    
                foreach (var value in values)
                {
                    sb.Append(ToCsv(value.Value));
                    sb.Append(",");
                }
                sb.Remove(sb.Length - 1, 1);//the last ','
                sb.Append(Environment.NewLine);
            }
            catch (Exception e1)
            {
                 //do something
            }
        }
        textWriter.Write(sb.ToString());
    
        return sb.ToString();
    }
    
    //Help function that encode text to csv:
    public static string ToCsv(string input)
    {
        if (input != null)
        {
            input = input.Replace("\r\n", string.Empty)
                .Replace("\r", string.Empty)
                .Replace("\n", string.Empty);
            if (input.Contains("\""))
            {
                input = input.Replace("\"", "\"\"");
            }
    
            input = "\"" + input + "\"";
        }
    
        return input;
    }
    

    This is the most important function, Its extracting the properties values out of (almost) any generic class.

    private Dictionary GetPropertiesValues(object item, Dictionary headers)
    {
        Dictionary values = new Dictionary();
        if (item == null)
        {
            return values;
        }
    
        //We need to make sure each value is coordinated with the headers, empty string 
        foreach (var key in headers.Keys)
        {
            values[key] = String.Empty;
        }
    
        Type t = item.GetType();
        PropertyInfo[] propertiesInfo = t.GetProperties();
    
        foreach (PropertyInfo propertiyInfo in propertiesInfo)
        {
            //it not complex: string, int, bool, Enum
            if ((propertiyInfo.PropertyType.Module.ScopeName == "CommonLanguageRuntimeLibrary") || propertiyInfo.PropertyType.IsEnum)
            {
                if (headers.ContainsKey(propertiyInfo.Name))
                {
                    var value = propertiyInfo.GetValue(item, null);
                    if (value != null)
                    {
                        values[propertiyInfo.Name] = value.ToString();
                    }                         
                }
            }
            else//It's complex property
            {
                if (propertiyInfo.GetIndexParameters().Length == 0)
                {
                    Dictionary lst = GetPropertiesValues(propertiyInfo.GetValue(item, null), headers);
                    foreach (var value in lst)
                    {
                        if (!string.IsNullOrEmpty(value.Value))
                        {
                            values[value.Key] = value.Value;
                        }
                    }
                }
            }
        }
        return values;
    }
    

    Example for GetPropertiesValues:

    public MyClass 
    {
        public string Name {get; set;}
        public MyEnum Type {get; set;}
        public MyClass2 Child {get; set;}
    }
    public MyClass2
    {
        public int Age {get; set;}
        public DateTime MyDate {get; set;}
    }
    
    MyClass myClass = new MyClass()
    {
        Name = "Bruce",
        Type = MyEnum.Sometype,
        Child = new MyClass2()
        {
            Age = 18,
            MyDate = DateTime.Now()
        }
    };
    
    Dictionary headers = new Dictionary();
    headers.Add("Name", "CustomCaption_Name");
    headers.Add("Type", "CustomCaption_Type");
    headers.Add("Age", "CustomCaption_Age");
    
    GetPropertiesValues(myClass, headers)); // OUTPUT: {{"Name","Bruce"},{"Type","Sometype"},{"Age","18"}}
    

提交回复
热议问题