//-----------------------------------------------------------------------
//
// 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));
}
}
}