namespace Unosquare.Swan.Formatters
{
using Reflection;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
///
/// A CSV writer useful for exporting a set of objects.
///
///
/// The following code describes how to save a list of objects into a CSV file.
///
/// using System.Collections.Generic;
/// using Unosquare.Swan.Formatters;
///
/// class Example
/// {
/// class Person
/// {
/// public string Name { get; set; }
/// public int Age { get; set; }
/// }
///
/// static void Main()
/// {
/// // create a list of people
/// var people = new List<Person>
/// {
/// new Person { Name = "Artyom", Age = 20 },
/// new Person { Name = "Aloy", Age = 18 }
/// }
///
/// // write items inside file.csv
/// CsvWriter.SaveRecords(people, "C:\\Users\\user\\Documents\\file.csv");
///
/// // output
/// // | Name | Age |
/// // | Artyom | 20 |
/// // | Aloy | 18 |
/// }
/// }
///
///
public class CsvWriter : IDisposable
{
private static readonly PropertyTypeCache TypeCache = new PropertyTypeCache();
private readonly object _syncLock = new object();
private readonly Stream _outputStream;
private readonly Encoding _encoding;
private readonly bool _leaveStreamOpen;
private bool _isDisposing;
private ulong _mCount;
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The output stream.
/// if set to true [leave open].
/// The encoding.
public CsvWriter(Stream outputStream, bool leaveOpen, Encoding encoding)
{
_outputStream = outputStream;
_encoding = encoding;
_leaveStreamOpen = leaveOpen;
}
///
/// Initializes a new instance of the class.
/// It automatically closes the stream when disposing this writer.
///
/// The output stream.
/// The encoding.
public CsvWriter(Stream outputStream, Encoding encoding)
: this(outputStream, false, encoding)
{
// placeholder
}
///
/// Initializes a new instance of the class.
/// It uses the Windows 1252 encoding and automatically closes
/// the stream upon disposing this writer.
///
/// The output stream.
public CsvWriter(Stream outputStream)
: this(outputStream, false, Definitions.Windows1252Encoding)
{
// placeholder
}
///
/// Initializes a new instance of the class.
/// It opens the file given file, automatically closes the stream upon
/// disposing of this writer, and uses the Windows 1252 encoding.
///
/// The filename.
public CsvWriter(string filename)
: this(File.OpenWrite(filename), false, Definitions.Windows1252Encoding)
{
// placeholder
}
///
/// Initializes a new instance of the class.
/// It opens the file given file, automatically closes the stream upon
/// disposing of this writer, and uses the given text encoding for output.
///
/// The filename.
/// The encoding.
public CsvWriter(string filename, Encoding encoding)
: this(File.OpenWrite(filename), false, encoding)
{
// placeholder
}
#endregion
#region Properties
///
/// Gets or sets the field separator character.
///
///
/// The separator character.
///
public char SeparatorCharacter { get; set; } = ',';
///
/// Gets or sets the escape character to use to escape field values.
///
///
/// The escape character.
///
public char EscapeCharacter { get; set; } = '"';
///
/// Gets or sets the new line character sequence to use when writing a line.
///
///
/// The new line sequence.
///
public string NewLineSequence { get; set; } = Environment.NewLine;
///
/// Defines a list of properties to ignore when outputting CSV lines.
///
///
/// The ignore property names.
///
public List IgnorePropertyNames { get; } = new List();
///
/// Gets number of lines that have been written, including the headings line.
///
///
/// The count.
///
public ulong Count
{
get
{
lock (_syncLock)
{
return _mCount;
}
}
}
#endregion
#region Helpers
///
/// Saves the items to a stream.
/// It uses the Windows 1252 text encoding for output.
///
/// The type of enumeration.
/// The items.
/// The stream.
/// true if stream is truncated, default false.
/// Number of item saved.
public static int SaveRecords(IEnumerable items, Stream stream, bool truncateData = false)
{
// truncate the file if it had data
if (truncateData && stream.Length > 0)
stream.SetLength(0);
using (var writer = new CsvWriter(stream))
{
writer.WriteHeadings();
writer.WriteObjects(items);
return (int)writer.Count;
}
}
///
/// Saves the items to a CSV file.
/// If the file exits, it overwrites it. If it does not, it creates it.
/// It uses the Windows 1252 text encoding for output.
///
/// The type of enumeration.
/// The items.
/// The file path.
/// Number of item saved.
public static int SaveRecords(IEnumerable items, string filePath) => SaveRecords(items, File.OpenWrite(filePath), true);
#endregion
#region Generic, main Write Line Method
///
/// Writes a line of CSV text. Items are converted to strings.
/// If items are found to be null, empty strings are written out.
/// If items are not string, the ToStringInvariant() method is called on them.
///
/// The items.
public void WriteLine(params object[] items)
=> WriteLine(items.Select(x => x == null ? string.Empty : x.ToStringInvariant()));
///
/// Writes a line of CSV text. Items are converted to strings.
/// If items are found to be null, empty strings are written out.
/// If items are not string, the ToStringInvariant() method is called on them.
///
/// The items.
public void WriteLine(IEnumerable