82 lines
2.4 KiB
C#
82 lines
2.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Elwig.Helpers.Export {
|
|
public abstract class Csv<T> : IExporter<T> {
|
|
|
|
public static string FileExtension => "csv";
|
|
|
|
private readonly StreamWriter _writer;
|
|
protected readonly char Separator;
|
|
protected string? Header;
|
|
|
|
public Csv(string filename, char separator = ';') :
|
|
this(filename, separator, Utils.UTF8) {
|
|
}
|
|
|
|
public Csv(string filename, char separator, Encoding encoding) {
|
|
_writer = new StreamWriter(filename, false, encoding);
|
|
Separator = separator;
|
|
}
|
|
|
|
public void Dispose() {
|
|
GC.SuppressFinalize(this);
|
|
_writer.Dispose();
|
|
}
|
|
|
|
public ValueTask DisposeAsync() {
|
|
GC.SuppressFinalize(this);
|
|
return _writer.DisposeAsync();
|
|
}
|
|
|
|
public async Task ExportAsync(IEnumerable<T> data, IProgress<double>? progress = null) {
|
|
progress?.Report(0.0);
|
|
int count = data.Count() + 2, i = 0;
|
|
|
|
if (Header != null) await _writer.WriteLineAsync(Header);
|
|
progress?.Report(100.0 * ++i / count);
|
|
|
|
foreach (var row in data) {
|
|
await _writer.WriteLineAsync(FormatRow(row));
|
|
progress?.Report(100.0 * ++i / count);
|
|
}
|
|
|
|
await _writer.FlushAsync();
|
|
progress?.Report(100.0);
|
|
}
|
|
|
|
public void Export(IEnumerable<T> data, IProgress<double>? progress = null) {
|
|
ExportAsync(data, progress).GetAwaiter().GetResult();
|
|
}
|
|
|
|
public string FormatRow(IEnumerable row) {
|
|
return string.Join(Separator, row);
|
|
}
|
|
|
|
public abstract string FormatRow(T row);
|
|
}
|
|
|
|
public class CsvSimple : Csv<IEnumerable<object?>> {
|
|
|
|
public CsvSimple(string filename, char separator, Encoding encoding) :
|
|
base(filename, separator, encoding) {
|
|
}
|
|
|
|
public CsvSimple(string filename, char separator = ';') :
|
|
base(filename, separator) {
|
|
}
|
|
|
|
public override string FormatRow(IEnumerable<object?> row) {
|
|
return string.Join(Separator, row.Select(i => {
|
|
var str = $"{i}";
|
|
return str.Contains(Separator) || str.Contains('\n') ? $"\"{str.Replace("\"", "\"\"")}\"" : str;
|
|
}));
|
|
}
|
|
}
|
|
}
|