using CsvHelper; using CsvHelper.Configuration; using Microsoft.Extensions.Logging; using SQLVision.Core.Models; using System.Data; namespace SQLVision.Services.Exporters; public class CsvExporter : IExportHandler { private readonly ILogger _logger; public string FormatName => "CSV"; public CsvExporter(ILogger logger) { _logger = logger; } public async Task ExportAsync(DataTable data, string filePath, ExportOptions options) { var config = new CsvConfiguration(System.Globalization.CultureInfo.CurrentCulture) { Delimiter = options.CustomOptions.TryGetValue("Delimiter", out var delimiter) ? delimiter.ToString() ?? "," : "," }; using var writer = new StreamWriter(filePath); using var csv = new CsvWriter(writer, config); // Запись заголовков if (options.IncludeHeaders) { foreach (DataColumn column in data.Columns) { csv.WriteField(column.ColumnName); } csv.NextRecord(); } // Запись данных foreach (DataRow row in data.Rows) { for (int i = 0; i < data.Columns.Count; i++) { csv.WriteField(row[i]); } csv.NextRecord(); } await csv.FlushAsync(); _logger.LogInformation("Exported {Rows} rows to CSV: {FilePath}", data.Rows.Count, filePath); } public async Task ExportToMemoryAsync(DataTable data, ExportOptions options) { using var stream = new MemoryStream(); using var writer = new StreamWriter(stream); using var csv = new CsvWriter(writer, System.Globalization.CultureInfo.CurrentCulture); // Запись заголовков if (options.IncludeHeaders) { foreach (DataColumn column in data.Columns) { csv.WriteField(column.ColumnName); } csv.NextRecord(); } // Запись данных foreach (DataRow row in data.Rows) { for (int i = 0; i < data.Columns.Count; i++) { csv.WriteField(row[i]); } csv.NextRecord(); } await csv.FlushAsync(); await writer.FlushAsync(); return stream.ToArray(); } }