/// <summary>
/// Creates a comma delimeted string of all the objects property values names.
/// </summary>
/// <param name="obj">object.</param>
/// <returns>string.</returns>
public static string ObjectToCsvData(object obj)
{
if (obj == null)
{
throw new ArgumentNullException("obj", "Value can not be null or Nothing!");
}
StringBuilder sb = new StringBuilder();
Type t = obj.GetType();
PropertyInfo[] pi = t.GetProperties();
for (int index = 0; index < pi.Length; index++)
{
sb.Append(pi[index].GetValue(obj, null));
if (index < pi.Length - 1)
{
sb.Append(",");
}
}
return sb.ToString();
}
public class CsvFileWriter
{
public static void WriteToFile<T>(string filePath, List<T> objs, string[] propertyNames)
{
var builder = new StringBuilder();
var propertyInfos = RelevantPropertyInfos<T>(propertyNames);
foreach (var obj in objs)
builder.AppendLine(CsvDataFor(obj, propertyInfos));
File.WriteAllText(filePath, builder.ToString());
}
public static void WriteToFileSingleFieldOneLine<T>(string filePath, List<T> objs, string propertyName)
{
var builder = new StringBuilder();
var propertyInfos = RelevantPropertyInfos<T>(new[] { propertyName });
for (var i = 0; i < objs.Count; i++)
{
builder.Append(CsvDataFor(objs[i], propertyInfos));
if (i < objs.Count - 1)
builder.Append(",");
}
File.WriteAllText(filePath, builder.ToString());
}
public static string GetCSVData<T>(List<T> objs, string[] propertyNames, string[] renameHeaders)
{
var propertyInfos = RelevantPropertyInfos<T>(propertyNames);
var builder = new StringBuilder();
if (renameHeaders != null && renameHeaders.Count() > 0)
builder.AppendLine("\"" + String.Join("\",\"", renameHeaders.Select(i => i.Replace("\"", "'"))) + "\"");
else
builder.AppendLine(String.Join(",", propertyInfos.Select(i => i.Name).ToList()));
foreach (var obj in objs)
builder.AppendLine(CsvDataFor(obj, propertyInfos));
return builder.ToString();
}
private static List<PropertyInfo> RelevantPropertyInfos<T>(IEnumerable<string> propertyNames)
{
var propertyInfos = typeof(T).GetProperties().Where(p => propertyNames.Contains(p.Name)).ToDictionary(pi => pi.Name, pi => pi);
propertyInfos.Remove("EntityAspect");
// Adding related objects
foreach (var property in typeof(T).GetProperties())
{
if (property.PropertyType.Namespace == "System.Collections.Generic") // if property is a collection
{
var subType = property.PropertyType.GenericTypeArguments[0]; // Get the type of items in collection
var subProperties = subType.GetProperties().Where(p => propertyNames.Contains($"{property.Name}.{p.Name}")); // Get properties of related object
foreach (var subProperty in subProperties)
{
propertyInfos.Add($"{property.Name}.{subProperty.Name}", subProperty); // Add subproperties to propertyInfos
}
}
else if (!property.PropertyType.Namespace.StartsWith("System")) // if property is an object
{
var subProperties = property.PropertyType.GetProperties().Where(p => propertyNames.Contains($"{property.Name}.{p.Name}")); // Get properties of related object
foreach (var subProperty in subProperties)
{
propertyInfos.Add($"{property.Name}.{subProperty.Name}", subProperty); // Add subproperties to propertyInfos
}
}
}
return (from propertyName in propertyNames where propertyInfos.ContainsKey(propertyName) select propertyInfos[propertyName]).ToList();
}
private static string CsvDataFor<T>(T obj, List<PropertyInfo> propertyInfos)
{
var values = new List<string>();
foreach (var propertyInfo in propertyInfos)
{
try
{
// Check if it's a nested property
if (propertyInfo.ReflectedType.Name != obj.GetType().Name)
{
var property = typeof(T).GetProperty(propertyInfo.ReflectedType.Name);
if (property != null)
{
var subProperty = property.PropertyType.GetProperty(propertyInfo.Name);
if (subProperty != null)
{
if (property.PropertyType.Namespace == "System.Collections.Generic") // if it's a collection
{
var collection = property.GetValue(obj) as IEnumerable;
if (collection != null)
{
values.Add(String.Join(";", from object item in collection select subProperty.GetValue(item)?.ToString()));
}
else
{
values.Add(""); // Add empty value if collection is null
}
}
else // if it's a single object
{
var relatedObject = property.GetValue(obj);
if (relatedObject != null)
{
values.Add(subProperty.GetValue(relatedObject)?.ToString());
}
else
{
values.Add(""); // Add empty value if related object is null
}
}
}
else
{
values.Add(""); // Add empty value if subProperty not found
}
}
else
{
values.Add(""); // Add empty value if property not found
}
}
else
{
var value = propertyInfo.GetValue(obj);
values.Add(value == null ? "" : value.ToString());
}
}
catch (Exception ex)
{
// Handle any error that occurred during getting the value.
// This block will catch any unhandled exceptions and allow the loop to continue with the next property.
// Add error handling code here as needed.
values.Add(""); // Add empty value in case of error
}
}
//Join the string representations of the values with a comma and return the result.
return string.Join(",", values);
}
}
4条答案
按热度按时间qoefvg9y1#
示例代码显示了一种简单而强大的方法来实现您想要的功能,而无需硬编码属性名称(使用反射):
更多关于此:
Objects to CSV
How can i convert a list of objects to csv
Are there any CSV readers/writer lib’s in c#
Writing a CSV file in .net
LINQ to CSV : Getting data the way you want
LINQ to CSV library
lnxxn5zx2#
我采纳了Leniel的建议,并将其 Package 在一个功能齐全的“writer”中,该“writer”还允许您过滤想要写入的属性。下面是您的使用代码:
5f0d552i3#
v09wglhw4#
基于@mBria的代码,我更新了它,以便您可以使用点表示法提供相关的表属性: