122 lines
4.3 KiB
C#
122 lines
4.3 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using SQLVision.Core.Interfaces;
|
|
using SQLVision.Core.Models;
|
|
using SQLVision.Services.Exporters;
|
|
using System.Data;
|
|
|
|
namespace SQLVision.Services.Services;
|
|
|
|
public class ExportService : IExportService
|
|
{
|
|
private readonly ILogger<ExportService> _logger;
|
|
private readonly Dictionary<string, IExportHandler> _exportHandlers;
|
|
|
|
public ExportService(
|
|
ILogger<ExportService> logger,
|
|
IEnumerable<IExportHandler> exportHandlers)
|
|
{
|
|
_logger = logger;
|
|
_exportHandlers = exportHandlers.ToDictionary(h => h.FormatName, h => h);
|
|
}
|
|
|
|
public async Task ExportAsync(DataTable data, string filePath, ExportOptions options)
|
|
{
|
|
if (data == null) throw new ArgumentNullException(nameof(data));
|
|
|
|
var extension = Path.GetExtension(filePath).TrimStart('.').ToLower();
|
|
var format = options?.Format ?? GetFormatFromExtension(extension);
|
|
|
|
if (_exportHandlers.TryGetValue(format, out var handler))
|
|
{
|
|
try
|
|
{
|
|
await handler.ExportAsync(data, filePath, options ?? new ExportOptions());
|
|
_logger.LogInformation("Exported {Rows} rows to {FilePath} as {Format}",
|
|
data.Rows.Count, filePath, format);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error exporting to {Format}", format);
|
|
throw;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Export format '{format}' is not supported");
|
|
}
|
|
}
|
|
|
|
public async Task ExportAsync(DataSet dataSet, string filePath, ExportOptions options)
|
|
{
|
|
if (dataSet.Tables.Count == 0)
|
|
throw new InvalidOperationException("DataSet contains no tables");
|
|
|
|
if (dataSet.Tables.Count == 1)
|
|
{
|
|
await ExportAsync(dataSet.Tables[0], filePath, options);
|
|
}
|
|
else
|
|
{
|
|
// Для Excel создаем несколько листов
|
|
var extension = Path.GetExtension(filePath);
|
|
if (extension.Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
await ExportToMultiSheetExcel(dataSet, filePath, options);
|
|
}
|
|
else
|
|
{
|
|
// Для других форматов - экспортируем каждый лист в отдельный файл
|
|
var basePath = Path.Combine(Path.GetDirectoryName(filePath)!,
|
|
Path.GetFileNameWithoutExtension(filePath));
|
|
|
|
for (int i = 0; i < dataSet.Tables.Count; i++)
|
|
{
|
|
var table = dataSet.Tables[i];
|
|
var tableFilePath = $"{basePath}_{table.TableName}_{i + 1}{extension}";
|
|
await ExportAsync(table, tableFilePath, options);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task<byte[]> ExportToMemoryAsync(DataTable data, ExportOptions options)
|
|
{
|
|
var format = options?.Format ?? "Excel";
|
|
|
|
if (_exportHandlers.TryGetValue(format, out var handler))
|
|
{
|
|
return await handler.ExportToMemoryAsync(data, options ?? new ExportOptions());
|
|
}
|
|
|
|
throw new NotSupportedException($"Export format '{format}' is not supported");
|
|
}
|
|
|
|
private async Task ExportToMultiSheetExcel(DataSet dataSet, string filePath, ExportOptions options)
|
|
{
|
|
using var workbook = new ClosedXML.Excel.XLWorkbook();
|
|
|
|
for (int i = 0; i < dataSet.Tables.Count; i++)
|
|
{
|
|
var table = dataSet.Tables[i];
|
|
var worksheet = workbook.Worksheets.Add(table.TableName ?? $"Sheet{i + 1}");
|
|
|
|
// Используем ExcelExporter для записи данных
|
|
if (_exportHandlers.TryGetValue("Excel", out var excelHandler) &&
|
|
excelHandler is ExcelExporter excelExporter)
|
|
{
|
|
var excelOptions = options ?? new ExportOptions();
|
|
await excelExporter.ExportAsync(table, filePath, excelOptions);
|
|
}
|
|
}
|
|
|
|
await Task.Run(() => workbook.SaveAs(filePath));
|
|
}
|
|
|
|
private string GetFormatFromExtension(string extension) => extension switch
|
|
{
|
|
"xlsx" => "Excel",
|
|
"csv" => "CSV",
|
|
"json" => "JSON",
|
|
_ => "Excel"
|
|
};
|
|
} |