[C#] File exporter for IEnumerable of T

Scope

This article has the goal to show a solution for have a file exporter based in a list of items but not matter which type.

Introduction

Sometime ago was published the sample Export To CSV for Windows Store apps, this solution is generic, is dynamic because uses reflection and It allow to export a list of items to a csv file. In Windows Store apps uses Windows Runtime and reflection is a bit different from reflection in WPF, Asp.Net, …

In this sample ww will create the sample for a common .Net project.

Description

For help in the sample, let’s create a specific class Person.

    /// 
    /// Define the Person.
    /// 
    public class Person
    {
        /// 
        /// Gets or sets the name.
        /// 
        /// The name.
        public string Name { get; set; }

        /// 
        /// Gets or sets the age.
        /// 
        /// The age.
        public int Age { get; set; }

        /// 
        /// Gets or sets the birthday.
        /// 
        /// The birthday.
        public DateTime Birthday { get; set; }

        /// 
        /// Gets or sets the country.
        /// 
        /// The country.
        public string Country { get; set; }
    }

in class diagram we will have

person
After it, we will create the Export class that will have a generic method, that uses a generic type T. Something like as following

 

    /// 
    /// Define the Export File.
    /// 
    public static class Export
    {
        /// 
        /// Exporters the list of items that can include the specified include header line.
        /// 
        /// <typeparam name="T">The generic type.
        ///If set totrue [include header line].
        ///The separator.
        ///The items.
        /// The content file.
        public static string Exporter(bool includeHeaderLine, string separator, IEnumerable 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();
        }

        /// 
        /// Makes the value friendly.
        /// 
        ///The value.
        /// The string converted.
        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;
        } 
    }

The method Exporter will allow to include a header with the properties name and allow to define the separador between each field value. It is very interesting because I can use the ListSeparator ( , or  ; ), |, + or other we define.

The method MakeValueFriendly is only useful for format specific type like DateTime.

Now we can create a list of person and write it to a file, let’s see how!

    /// 
    /// Define the Program.
    /// 
    public class Program
    {
        /// 
        /// Defines the entry point of the application.
        /// 
        /// args">The arguments.
        static void Main(string[] args)
        {
            var people = GetPeople();
            var basePath = Directory.GetCurrentDirectory();

            var fullPath = Path.Combine(basePath, "mycsvfile_includeHeader.csv");

            // to cvs file
            File.WriteAllText(fullPath, Export.Exporter(true, System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator, people));

            fullPath = Path.Combine(basePath, "myfile_includeHeader.txt");

            // to a txt file
            File.WriteAllText(fullPath, Export.Exporter(true, "+", people));


            fullPath = Path.Combine(basePath, "mycsvfile.csv");

            // to cvs file
            File.WriteAllText(fullPath, Export.Exporter(true, System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator, people));

            fullPath = Path.Combine(basePath, "myfile.txt");

            // to a txt file
            File.WriteAllText(fullPath, Export.Exporter(true, "|", people));
        }

        /// 
        /// Gets the people.
        /// 
        /// The IEnumerable.
        private static IEnumerable GetPeople()
        {
            return new List
            {
                new Person { Name = "Mary", Age = 22, Birthday = new DateTime(1992, 03, 24), Country = "Ireland" },
                new Person { Name = "Peter", Age = 10, Birthday = new DateTime(2004, 01, 05), Country = "Portugal" },
                new Person { Name = "Anne", Age = 50, Birthday = new DateTime(1964, 11, 03), Country = "Spain" }
            };
        }
    }

In the sample provided, we get the people and then wrote it in a CSV file and a TXT file, where we selected the both cases (with header and without).

The ouput

Running the console application we will get the output

folder

The CSV file with header

The CSV file without header

The txt file with header

The CSV file without header

Source Code

The source code can be found in MSDN Samples.

Export to CSV [Windows 8 Store Apps]

Introduction

In this sample i will show a sample for  export data, that is showed in ListView, to a csv file.

You can get this here:
Export To CSV or in My MSDN Samples in GitHub

Building the Sample

You only need Visual Studio 2012 and Windows 8, both the RTM version.

Description

This sample could be called “Export to Excel”, but it is not supported, the only way is to write the data in a CSV file that can be opened in Excel.

 

Here is the class diagram:

 

 

Here is the class that is used to convert the data into a CSV file:

public class CsvExport<T> where T : class 
    { 
        public IList<T> Objects; 

        public CsvExport(IList<T> objects) 
        { 
            Objects = objects; 
        } 

        public string Export() 
        { 
            return Export(true); 
        } 

        public string Export(bool includeHeaderLine) 
        { 

            var sb = new StringBuilder(); 

            //Get properties using reflection. 
           var propertyInfos = typeof(T).GetTypeInfo(); 

            if (includeHeaderLine) 
            { 
                //add header line. 
                foreach (var propertyInfo in propertyInfos.DeclaredProperties) 
                { 
                    sb.Append(propertyInfo.Name).Append(";"); 
                } 
                sb.Remove(sb.Length - 1, 1).AppendLine(); 
            } 

            //add value for each property. 
            foreach (T obj in Objects) 
            { 
                foreach (var propertyInfo in propertyInfos.DeclaredProperties) 
                { 
                    sb.Append(MakeValueCsvFriendly(propertyInfo.GetValue(obj, null))).Append(";"); 
                } 
                sb.Remove(sb.Length - 1, 1).AppendLine(); 
            } 

            return sb.ToString(); 
        } 

        //export to a file. 
        public async void ExportToFile(string path) 
        { 
           var storageFolder = KnownFolders.DocumentsLibrary; 
           var file = await storageFolder.CreateFileAsync(path, CreationCollisionOption.ReplaceExisting); 
           await FileIO.WriteTextAsync(file, Export()); 
        } 

        //export as binary data. 
        public byte[] ExportToBytes() 
        { 
            return Encoding.UTF8.GetBytes(Export()); 
        } 

        //get the csv value for field. 
        private string MakeValueCsvFriendly(object value) 
        { 
            if (value == null) return ""; 

            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"); 
            } 
            string output = value.ToString(); 

            if (output.Contains(",") || output.Contains("\"")) 
                output = '"' + output.Replace("\"", "\"\"") + '"'; 

            return output; 

        } 
    }

Source Code Files

  • BoardItem is my item that has Name, Value and Count properties
  • ConvertingToCSVFileViewModel: is my view model to connect data with the view (i use binding)
  • CsvExport is the class that convert the data into csv file.

Result

In the Windows 8 App:

 

The myexportresult.csv file opened in Excel:


Build the Sample

  1. Start Visual Studio Express 2012 for Windows 8 and select File > Open > Project/Solution.
  2. Go to the directory in which you unzipped the sample. Go to the directory named for the sample, and double-click the Visual Studio Express 2012 for Windows 8 Solution (.sln) file.
  3. Press F7 or use Build > Build Solution to build the sample.

 Run the sample

To debug the app and then run it, press F5 or use Debug > Start Debugging. To run the app without   debugging, press Ctrl+F5 or use Debug > Start Without Debugging.

More Information

Ask me on twitter @saramgsilva