//----------------------------------------------------------------------- // // Copyright (c) 2010 Deltares. All rights reserved. // // B.S.T. The // tom.the@deltares.nl // 04-11-2010 // n.a. //----------------------------------------------------------------------- namespace Deltares.Dam.Data { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Globalization; using System.Reflection; public class CsvExporter { private const string NullValue = "NULL"; private const string Delimiter = ";"; private readonly string fileName; private readonly IEnumerable data; private string columnHeader; private bool headerWritten; public CsvExporter(string fileName, IEnumerable data) { this.data = data; ThrowHelper.ThrowWhenConditionIsTrue( StringResourceNames.OutputFileNameNotValid, () => string.IsNullOrEmpty(fileName) || fileName.Trim() == ""); this.fileName = fileName; headerWritten = false; WriteHeaderInFirstLine = true; } public bool WriteHeaderInFirstLine { get; set; } public void WriteFile() { using (TextWriter writer = new StreamWriter(this.fileName, false)) { foreach (T dataItem in data) { string line = GetDataItemString(dataItem); if (line.Trim() != "") { if (WriteHeaderInFirstLine && !headerWritten) { writer.WriteLine(columnHeader); headerWritten = true; } writer.WriteLine(line); } else { writer.WriteLine("No (public) properties are annotated with the column meta data CsvColumnAttribute."); } } } } private string GetDataItemString(T dataItem) { if (dataItem.Equals(default(T))) throw new CsvExporterException("Invalid export data item"); var header = new Dictionary(); var table = new Dictionary(); string line = ""; foreach (var pInfo in (typeof(T).GetProperties())) { foreach (Attribute attribute in pInfo.GetCustomAttributes(true)) { var attr = attribute as CsvExportColumnAttribute; if (null != attr) { ThrowWhenIndexAlreadyExists(header, attr.Index, pInfo.Name); header.Add(attr.Index, attr.Name); object value; try { value = pInfo.GetValue(dataItem, null) ?? NullValue; } catch (TargetInvocationException) { value = NullValue; } table.Add(attr.Index, value); } } } // assemble the data line if (table.Count > 0) { // order the keys by column index var keys = table.Keys.OrderBy(k => k); var counter = 0; foreach (var index in keys) { var val = string.Format(CultureInfo.InvariantCulture, "{0}", table[index]); line += val + (++counter < table.Count ? Delimiter : ""); } // assemble the column header if (WriteHeaderInFirstLine && string.IsNullOrEmpty(columnHeader)) { counter = 0; foreach (var index in keys) columnHeader += header[index] + (++counter < table.Count ? Delimiter : ""); } } return line; } private static void ThrowWhenIndexAlreadyExists(IDictionary dictionary, int index, string propertyName) { string message = string.Format(ThrowHelper.GetResourceString(StringResourceNames.CsvColumnIndexAlreadyExists), index, propertyName); ThrowHelper.ThrowWhenConditionIsTrue( message, () => dictionary.ContainsKey(index)); } } }