Scope
The purpose of this article is to show a solution for a file exporter based in a list of items regardless of type.
Introduction
Sometime ago the sample Export To CSV was published for Windows Store apps, this solution is generic, is dynamic because it uses reflection and allows export of a list of items to a CSV file. Windows Store apps uses Windows Runtime and reflection is a bit different from reflection in WPF, ASP.NET, and so on.
In this article we will create a sample for a common .Net project.
Description
For help in the sample, let's create a specific class Person.
- /// <summary>
- /// Define the Person.
- /// </summary>
- public class Person
- {
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- public string Name { get; set; }
- /// <summary>
- /// Gets or sets the age.
- /// </summary>
- /// <value>The age.</value>
- public int Age { get; set; }
- /// <summary>
- /// Gets or sets the birthday.
- /// </summary>
- /// <value>The birthday.</value>
- public DateTime Birthday { get; set; }
- /// <summary>
- /// Gets or sets the country.
- /// </summary>
- /// <value>The country.</value>
- public string Country { get; set; }
- }
In the class diagram we will have:
We will then create the Export class that will have a generic method, that uses a generic type T. Something such as the following:
- /// <summary>
- /// Define the Export File.
- /// </summary>
- public static class Export
- {
- /// <summary>
- /// Exporters the list of items that can include the specified include header line.
- /// </summary>
- /// <typeparam name="T">The generic type.</typeparam>
- /// <param name="includeHeaderLine">If set to <c>true</c> [include header line].</param>
- /// <param name="separator">The separator.</param>
- /// <param name="items">The items.</param>
- /// <returns>The content file.</returns>
- public static string Exporter<T>(bool includeHeaderLine, string separator, IEnumerable<T> items) where T : class
- {
- var sb = new StringBuilder();
- // Get properties using reflection.
- var properties = typeof(T).GetProperties();
- if (includeHeaderLine)
- {
- // add header line
- foreach (var property in properties)
- {
- sb.Append(property.Name).Append(separator);
- }
- sb.Remove(sb.Length - 1, 1).AppendLine();
- }
- // add value for each property.
- foreach (T item in items)
- {
- foreach (var property in properties)
- {
- sb.Append(MakeValueFriendly(property.GetValue(item, null))).Append(separator);
- }
- sb.Remove(sb.Length - 1, 1).AppendLine();
- }
- return sb.ToString();
- }
- /// <summary>
- /// Makes the value friendly.
- /// </summary>
- /// <param name="value">The value.</param>
- /// <returns>The string converted.</returns>
- private static string MakeValueFriendly(object value)
- {
- if (value == null)
- {
- return string.Empty;
- }
- if (value is DateTime)
- {
- if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
- {
- return ((DateTime)value).ToString("yyyy-MM-dd");
- }
- return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
- }
- var output = value.ToString();
- if (output.Contains(",") || output.Contains("""))
- {
- output = '"' + output.Replace(""", """") + '"';
- }
- return output;
- }
- }






Join the conversation! Your thoughts help the community grow.