From e5f9c43e391e9963c7c6a378bf78033a6a4a69bb Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Thu, 1 Feb 2024 18:58:41 +0300 Subject: [PATCH 01/12] add draft project --- Curiosity.Utils.sln | 10 + .../Readers/CsvFileDataReader.cs | 179 +++++++++++++ .../Readers/IFileDataReader.cs | 37 +++ .../Readers/XlsFileExtensions.cs | 18 ++ .../Readers/XlsxFileDataReader.cs | 210 ++++++++++++++++ .../Resources/LNG.cs | 27 ++ .../Resources/Strings.en.resx | 67 +++++ .../Resources/Strings.resx | 67 +++++ ...SIISLtd.Utils.FileDataReaderWriters.csproj | 27 ++ ...s.FileDataReaderWriters.csproj.DotSettings | 2 + .../Style/FontStyle.cs | 9 + .../Style/FormatSettings.cs | 32 +++ .../Style/TextAlignment.cs | 9 + .../Writers/CellData.cs | 16 ++ .../Writers/CsvFileWriter.cs | 79 ++++++ .../Writers/FlexCelXlsFileWriter.cs | 123 +++++++++ .../Writers/FlexCelXlsMultiFileWriter.cs | 172 +++++++++++++ .../Writers/IFileWriter.cs | 48 ++++ .../Writers/NpoiXlsFileWriter.cs | 192 ++++++++++++++ .../Writers/NpoiXlsMultiFileWriter.cs | 235 ++++++++++++++++++ .../Writers/XlsFileExtensions.cs | 20 ++ 21 files changed, 1579 insertions(+) create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/LNG.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.en.resx create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.resx create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj.DotSettings create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FontStyle.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FormatSettings.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/TextAlignment.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CellData.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/IFileWriter.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs create mode 100644 src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs diff --git a/Curiosity.Utils.sln b/Curiosity.Utils.sln index 242087b..5372659 100644 --- a/Curiosity.Utils.sln +++ b/Curiosity.Utils.sln @@ -151,6 +151,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.SMS.Iqsms", "src\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.SMS.Iqsms.Sample", "samples\Curiosity.SMS.Iqsms.Sample\Curiosity.SMS.Iqsms.Sample.csproj", "{4015E00D-EC76-4A73-A52F-4C4D71C6B8B5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SIISLtd.Utils.FileDataReaderWriters", "src\FileData\SIISLtd.Utils.FileDataReaderWriters\SIISLtd.Utils.FileDataReaderWriters.csproj", "{D135ADFA-0A52-41C0-876F-691876A780E1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileData", "FileData", "{2B8CCF93-24F0-45F9-9961-85695351141E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -341,6 +345,10 @@ Global {4015E00D-EC76-4A73-A52F-4C4D71C6B8B5}.Debug|Any CPU.Build.0 = Debug|Any CPU {4015E00D-EC76-4A73-A52F-4C4D71C6B8B5}.Release|Any CPU.ActiveCfg = Release|Any CPU {4015E00D-EC76-4A73-A52F-4C4D71C6B8B5}.Release|Any CPU.Build.0 = Release|Any CPU + {D135ADFA-0A52-41C0-876F-691876A780E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D135ADFA-0A52-41C0-876F-691876A780E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D135ADFA-0A52-41C0-876F-691876A780E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D135ADFA-0A52-41C0-876F-691876A780E1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -414,6 +422,8 @@ Global {97ED36AE-E975-4CF8-BDDB-226DB0032531} = {7CFB0FEF-A83E-41F5-AAF7-61B84D18D243} {9CE5443D-D7D5-45DA-B32E-7776AAC4FFC5} = {EEB0E172-4687-434F-A91B-3E7D3C60C8F8} {4015E00D-EC76-4A73-A52F-4C4D71C6B8B5} = {A7A87B49-2E4C-4A0A-92F4-7C7849F36A84} + {2B8CCF93-24F0-45F9-9961-85695351141E} = {7C485CBA-A08F-4A0E-835A-4505CBBB7EA8} + {D135ADFA-0A52-41C0-876F-691876A780E1} = {2B8CCF93-24F0-45F9-9961-85695351141E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BA1A20A2-0D4E-492D-877C-0A36F18FBFF1} diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs new file mode 100644 index 0000000..b6f2936 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs @@ -0,0 +1,179 @@ +using System.Text; +using SIISLtd.SSNG.Common.Guards; +using Sylvan.Data.Csv; + +namespace SIISLtd.Utils.FileDataReaderWriters.Readers; + +/// +/// Класс для построчного чтения CSV файлов. +/// +/// +public class CsvFileDataReader : IFileDataReader +{ + /// + /// Максимальное количество пустых строк подряд, после которых мы перестаем читать файл. + /// + private const int MaxSequentialEmptyRowsCount = 10; + + private readonly StreamReader _streamReader; + private readonly CsvDataReader _csvReader; + + private readonly Stream _fileStream; + private readonly bool _disposeFileStream; + + private int _rIdx; + private int _sequentialEmptyRowsCount; + private readonly int _startRowIdx; + + private IReadOnlyList? _currentRow; + private readonly List _rowStringBuffer; + private object[] _rowObjectBuffer; + + /// + public int MaxSupportedRowsCount => int.MaxValue; + + /// + /// + /// Уменьшаем на 1, потому что после чтения мы всегда увеличиваем после чтения очередной строки. + /// + public int CurrentRowIdx => _rIdx - 1; + + private CsvFileDataReader( + Stream fileStream, + bool disposeFileStream, + int? columnsCount, + Encoding encoding, + char delimiter, + int startRowIdx) + { + _fileStream = fileStream; + _disposeFileStream = disposeFileStream; + + _streamReader = new StreamReader(fileStream, encoding, false, 128 * 1024); + _csvReader = CsvDataReader.Create( + _streamReader, + new CsvDataReaderOptions + { + Delimiter = delimiter, + HasHeaders = false, // мы обычно сами парсим заголовки, поэтому нет смысла что-то там парсить + }); + + _rowStringBuffer = columnsCount.HasValue + ? new List(columnsCount.Value) + : new List(); + // если что, массив может быть пересоздан, если мы не знаем точное количество колонок + _rowObjectBuffer = new object[columnsCount ?? 256]; + + _rIdx = 1; + _startRowIdx = Math.Max(_rIdx, startRowIdx); + _sequentialEmptyRowsCount = 0; + } + + /// + /// Создает готовый к работе . + /// + /// Поток с данными файла. + /// Количество колонок в CSV файле. Если не указано, то количество колонок в каждой строке будет определяться автоматически. + /// Номер строки, начиная с которой надо читать файл. + /// Разделитель колонок. + /// Кодировка файлов. Если не указано используем UTF-8 + /// Нужно ли освобождать после завершения чтения. + public static CsvFileDataReader CreateReader( + Stream fileStream, + int? columnsCount = null, + int startRowIdx = 1, + char fieldDelimiter = ';', + Encoding? encoding = null, + bool disposeFileStream = false) + { + Guard.AssertNotNull(fileStream, nameof(fileStream)); + Guard.AssertNotNegative(columnsCount, nameof(columnsCount)); + Guard.AssertNotNegative(startRowIdx, nameof(startRowIdx)); + + return new CsvFileDataReader( + fileStream, + disposeFileStream, + columnsCount, + encoding ?? Encoding.UTF8, + fieldDelimiter, + startRowIdx); + } + + /// + public bool Read() + { + while (true) + { + if (_rIdx > MaxSupportedRowsCount) return false; + if (_sequentialEmptyRowsCount > MaxSequentialEmptyRowsCount) return false; + + _rowStringBuffer.Clear(); + var isEmptyRow = true; + if (_csvReader.Read()) + { + // пропускаем заголовки и прочее + if (_rIdx >= _startRowIdx) + { + // количество ячеек в строке может меняться + // до начала работ мы не можем знать, сколько их там, + // поэтому адаптируем размер буфера для чтения + var factColumnsCount = _csvReader.RowFieldCount; + if (factColumnsCount > _rowObjectBuffer.Length) + { + _rowObjectBuffer = new object[factColumnsCount]; + } + + var columnsCount = _csvReader.GetValues(_rowObjectBuffer); + for (var cIdx = 0; cIdx < columnsCount; cIdx++) + { + var cellValue = _rowObjectBuffer[cIdx].ToString()?.Trim(); + + if (String.IsNullOrWhiteSpace(cellValue)) + { + _rowStringBuffer.Add(null); + } + else + { + isEmptyRow = false; + _rowStringBuffer.Add(cellValue); + } + } + } + } + + _rIdx++; + + if (isEmptyRow) + { + _sequentialEmptyRowsCount++; + _currentRow = null; + + // если прочитали пустую строку, попробуем прочитать еще одну строку, + // чтобы упростить клиентский код и не добавлять в него парсинг пустых строк + + continue; + } + + // если какие-то данные были, сбросим счетчик пустых строк + _sequentialEmptyRowsCount = 0; + + // сохраним данные, чтобы вернуть по требованию + _currentRow = _rowStringBuffer; + + return true; + } + } + + /// + public IReadOnlyList? GetRow() => _currentRow; + + /// + public void Dispose() + { + _csvReader.Dispose(); + _streamReader.Dispose(); + + if (_disposeFileStream) + _fileStream.Dispose(); + } +} diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs new file mode 100644 index 0000000..fc1477c --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs @@ -0,0 +1,37 @@ +namespace SIISLtd.Utils.FileDataReaderWriters.Readers; + +/// +/// Общий интерфейс для классов, которые читает загруженные файлы построчно. +/// +/// +/// Реализации должны внутри себя инкапсулировать все работу по чтению файла, обработке пустых строк. +/// +public interface IFileDataReader : IDisposable +{ + /// + /// Максимальное количество строк для данного типа файла. + /// + /// + /// Нужно для того, чтобы не пытаться бесконечно читать данные из файла. + /// + int MaxSupportedRowsCount { get; } + + /// + /// Номер текущей строки, которая прочитана. + /// + int CurrentRowIdx { get; } + + /// + /// Читает очередную строку в память и обрабатывает ее. + /// + /// Была ли прочитана еще одна строка? + /// + /// Данные строки можно получить через . + /// + bool Read(); + + /// + /// Возвращает текущую прочитанную строку в виде отдельных ячеек. + /// + IReadOnlyList? GetRow(); +} diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs new file mode 100644 index 0000000..9a1fbce --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs @@ -0,0 +1,18 @@ +using FlexCel.XlsAdapter; + +namespace SIISLtd.Utils.FileDataReaderWriters.Readers +{ + /// + /// Методы расширения для в TMS FlexCell + /// + internal static class XlsFileExtensions + { + /// + /// Возвращает обрезанную строку из указанной ячейки или пустую строку, если в ячейке ничего нет + /// + public static string GetTrimmedStringFromCell(this XlsFile xls, int rIdx, int cIdx) + { + return (xls.GetStringFromCell(rIdx, cIdx) ?? String.Empty).Trim(); + } + } +} diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs new file mode 100644 index 0000000..c8a51f4 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs @@ -0,0 +1,210 @@ +using FlexCel.Core; +using FlexCel.XlsAdapter; +using SIISLtd.SSNG.Common; +using SIISLtd.SSNG.Common.Guards; +using SIISLtd.SSNG.Exceptions; +using SIISLtd.Utils.FileDataReaderWriters.Resources; + +namespace SIISLtd.Utils.FileDataReaderWriters.Readers; + +/// +/// Класс для построчного чтения данных их Xlsx/xlsx файлов. +/// +/// +public class XlsxFileDataReader : IFileDataReader +{ + /// + /// Максимальное количество пустых строк подряд, после которых мы перестаем читать файл. + /// + private const int MaxSequentialEmptyRowsCount = 10; + + private readonly Stream _fileStream; + private readonly bool _disposeFileStream; + + private XlsFile? _xls; + private readonly int? _columnsCount; + private readonly int _maxColumnsCount; + + private int _rIdx; + private int _sequentialEmptyRowsCount; + + private IReadOnlyList? _currentRow; + private readonly List _buffer; + + /// + public int MaxSupportedRowsCount => ExcelConstants.XlsxRowsMax; + + /// + /// + /// Уменьшаем на 1, потому что после чтения мы всегда увеличиваем после чтения очередной строки. + /// + public int CurrentRowIdx => _rIdx - 1; + + private XlsxFileDataReader( + Stream fileStream, + bool disposeFileStream, + XlsFile xls, + int? columnsCount, + int maxColumnsCount, + int startRowIdx) + { + Guard.AssertNotNull(fileStream, nameof(fileStream)); + Guard.AssertNotNull(xls, nameof(xls)); + + _fileStream = fileStream; + _disposeFileStream = disposeFileStream; + + _xls = xls; + _columnsCount = columnsCount; + _maxColumnsCount = maxColumnsCount; + + _buffer = columnsCount.HasValue + ? new List(columnsCount.Value) + : new List(); + + _rIdx = Math.Max(1, startRowIdx); + _sequentialEmptyRowsCount = 0; + } + + /// + /// Создает готовый к работе . + /// + /// Поток с данными файла. + /// Количество колонок в Excel файле. Если не указано, то количество колонок в каждой строке будет определяться автоматически. + /// Номер строки, начиная с которой надо читать файл. + /// Нужно ли освобождать после завершения чтения. + public static XlsxFileDataReader CreateReader( + string fileName, + Stream fileStream, + int? columnsCount = null, + int startRowIdx = 1, + bool disposeFileStream = false) + { + Guard.AssertNotNull(fileStream, nameof(fileStream)); + Guard.AssertNotEmpty(fileName, nameof(fileName)); + Guard.AssertNotNegative(columnsCount, nameof(columnsCount)); + Guard.AssertNotNegative(startRowIdx, nameof(startRowIdx)); + + var xls = new XlsFile(); + + TFileFormats fileFormat; + int maxColumnsCount; + var fileExtension = Path.GetExtension(fileName).ToLower(); + switch (fileExtension) + { + case ".xls": + fileFormat = TFileFormats.Xls; + maxColumnsCount = ExcelConstants.XlsColMax; + break; + case ".xlsx": + fileFormat = TFileFormats.Xlsx; + maxColumnsCount = ExcelConstants.XlsxColMax; + break; + default: + throw new ArgumentOutOfRangeException(nameof(fileName), fileName, + LNG.Get("Файл с расширением \"{0}\" не является Excel (.xls/.xlsx)", fileExtension)); + } + + ColumnImportType[]? columnFormats = null; + if (columnsCount != null) + { + columnFormats = new ColumnImportType[columnsCount.Value]; + for (var i = 0; i < columnsCount; i++) + { + columnFormats[i] = ColumnImportType.Text; + } + } + + // для xlsx пофиг на разделитель, просто сигнатура метода кривая, + // надо хоть что-то указать + var fieldDelimiter = ','; + xls.Open(fileStream, fileFormat, fieldDelimiter, 1, 1, columnFormats); + + // выбираем первый лист + if (xls.SheetCount < 1) + throw new UserException(LNG.Get("Файл должен содержать хотя бы один лист")); + + xls.ActiveSheet = 1; + + return new XlsxFileDataReader( + fileStream, + disposeFileStream, + xls, + columnsCount, + maxColumnsCount, + startRowIdx); + } + + /// + public bool Read() + { + while (true) + { + if (_rIdx > MaxSupportedRowsCount) return false; + if (_sequentialEmptyRowsCount > MaxSequentialEmptyRowsCount) return false; + + _buffer.Clear(); + var isEmptyRow = true; + + // используется, если мы не знаем количество колонок на момент чтения файла + var emptyCells = 0; + const int maxSequenceEmptyCellsCount = 10; + + // условия выхода из цикла ниже в первых строках + for (var cIdx = 1; ; cIdx++) + { + // если знаем количество колонок и вышли за границы, то выходим + if (_columnsCount.HasValue && cIdx > _columnsCount.Value) break; + // если не знаем количество колонок и много пустых ячеек подряд, то выходим + if (!_columnsCount.HasValue && emptyCells >= maxSequenceEmptyCellsCount) break; + // если вышли за граница файла, то тоже выходим + if (cIdx >= _maxColumnsCount) break; + + var cellValue = _xls!.GetTrimmedStringFromCell(_rIdx, cIdx); + if (cellValue.Length == 0) + { + emptyCells++; + _buffer.Add(null); + } + else + { + isEmptyRow = false; + emptyCells = 0; + _buffer.Add(cellValue); + } + } + + _rIdx++; + + if (isEmptyRow) + { + _sequentialEmptyRowsCount++; + _currentRow = null; + + // если прочитали пустую строку, попробуем прочитать еще одну строку, + // чтобы упростить клиентский код + continue; + } + + // если какие-то данные были, сбросим счетчик пустых строк + _sequentialEmptyRowsCount = 0; + + // сохраним данные, чтобы вернуть по требованию + _currentRow = _buffer; + + return true; + } + } + + /// + public IReadOnlyList? GetRow() => _currentRow; + + /// + public void Dispose() + { + _xls = null!; + + if (_disposeFileStream) + _fileStream.Dispose(); + } +} diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/LNG.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/LNG.cs new file mode 100644 index 0000000..81dcc54 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/LNG.cs @@ -0,0 +1,27 @@ +using System.Globalization; +using SIISLtd.Utils.Localization; + +namespace SIISLtd.Utils.FileDataReaderWriters.Resources +{ + internal static class LNG + { + private static readonly LocalizerCore Localizer; + private static readonly LocalizationOptions Options; + + static LNG() + { + Options = new LocalizationOptions(); + Localizer = new LocalizerCore(typeof(LNG).Assembly, Options); + } + + public static string Get(string source, params object[] arguments) + { + return Localizer.Get(Options.Prefix, source, false, arguments); + } + + public static string GetForCulture(CultureInfo culture, string source, params object[] arguments) + { + return Localizer.GetForCulture(culture, Options.Prefix, source, false, arguments); + } + } +} diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.en.resx b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.en.resx new file mode 100644 index 0000000..02f31ed --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.en.resx @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + File with extension "{0}" is not Excel (.xls/.xlsx) + + + File must contain at least one sheet + + \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.resx b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.resx new file mode 100644 index 0000000..eade2a3 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.resx @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Файл с расширением "{0}" не является Excel (.xls/.xlsx) + + + Файл должен содержать хотя бы один лист + + \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj new file mode 100644 index 0000000..4d10c4a --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj @@ -0,0 +1,27 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + $(NoWarn);1591 + $(NoWarn);1573 + + + + + + + + diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj.DotSettings b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj.DotSettings new file mode 100644 index 0000000..0b1e95c --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj.DotSettings @@ -0,0 +1,2 @@ + + False \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FontStyle.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FontStyle.cs new file mode 100644 index 0000000..0c75ba2 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FontStyle.cs @@ -0,0 +1,9 @@ +namespace SIISLtd.Utils.FileDataReaderWriters.Style; + +[Flags] +public enum FontStyle +{ + None = 0, + Bold = 0x01, + Italic = 0x02 +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FormatSettings.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FormatSettings.cs new file mode 100644 index 0000000..b08a721 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FormatSettings.cs @@ -0,0 +1,32 @@ +namespace SIISLtd.Utils.FileDataReaderWriters.Style; + +/// +/// Настройки формата ячеек +/// +public class FormatSettings +{ + /// + /// Начертание шрифта + /// + public FontStyle FontStyle { get; set; } + + /// + /// Горизонтальное выранивание текста + /// + public TextAlignment TextAlignment { get; set; } + + /// + /// Перенос слов на новую строку + /// + public bool WrapText { get; set; } + + /// + /// Размер шрифта в пунктах + /// + public int FontSize { get; set; } = 10; + + /// + /// Строка, указывающая формат (текст/число/деньги и т.д.). Можно посмотреть в форматах Excel + /// + public string DataFormat { get; set; } = "@"; +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/TextAlignment.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/TextAlignment.cs new file mode 100644 index 0000000..e1fd71a --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/TextAlignment.cs @@ -0,0 +1,9 @@ +namespace SIISLtd.Utils.FileDataReaderWriters.Style; + +public enum TextAlignment +{ + Left = 0, + Center = 1, + Right = 2, + Justify = 3 +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CellData.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CellData.cs new file mode 100644 index 0000000..f8cf211 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CellData.cs @@ -0,0 +1,16 @@ +namespace SIISLtd.Utils.FileDataReaderWriters; + +/// +/// Данные ячейки с форматом +/// +public class CellData +{ + public object? Value { get; } + public int? Format { get; } + + public CellData(object? value, int? format = null) + { + Value = value; + Format = format; + } +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs new file mode 100644 index 0000000..8bb998b --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs @@ -0,0 +1,79 @@ +using System.Text; +using CsvHelper; +using CsvHelper.Configuration; +using FlexCel.Core; +using SIISLtd.Utils.FileDataReaderWriters.Style; +using SIISLtd.Utils.Tools.Localization; + +namespace SIISLtd.Utils.FileDataReaderWriters; + +/// +/// Запись данных в .csv формате +/// +/// +/// Расходует мало памяти, потому что запись идёт через потоки с буферизацией +/// +public class CsvFileWriter : IFileWriter +{ + private readonly StreamWriter _streamWriter; + private readonly CsvWriter _csvWriter; + + public CsvFileWriter(string outputFilePath) + { + var configuration = new CsvConfiguration(LngHelper.CurrentCulture) + { + Delimiter = ";", + Mode = CsvMode.RFC4180, + Encoding = Encoding.UTF8, + }; + + _streamWriter = new StreamWriter(outputFilePath); + _csvWriter = new CsvWriter(_streamWriter, configuration); + } + + public int AddFormat(FormatSettings formatSettings) => 0; + + public int AddDefaultFormat() => 0; + + public void AddHeaders(IReadOnlyList data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + + AppendLine(data); + } + + public void AppendLine(IReadOnlyList data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + Append(data[i].Value); + } + + EndLine(); + } + + public void Append(object? value, int? format = null) + { + _csvWriter.WriteField(value); + } + + public void EndLine() + { + // библиотека сама флашит строки периодически + _csvWriter.NextRecord(); + } + + public void Flush() + { + _csvWriter.Flush(); + _streamWriter.Flush(); + } + + public void Dispose() + { + _csvWriter.Dispose(); + _streamWriter.Dispose(); + } +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs new file mode 100644 index 0000000..3cf5a31 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs @@ -0,0 +1,123 @@ +using System.Text; +using FlexCel.Core; +using FlexCel.XlsAdapter; +using SIISLtd.Utils.FileDataReaderWriters.Style; + +namespace SIISLtd.Utils.FileDataReaderWriters; + +/// +/// Запись данных в xlsx / xls формате +/// +public class FlexCelXlsFileWriter : IFileWriter +{ + private readonly XlsFile _xls; + + private IReadOnlyList? _headers; + + private readonly string _outputFilePath; + private readonly TFileFormats _fileFormat; + private readonly bool _isNeedToFitHeader; + + private int _currentRow = 1; + private int _currentCell = 1; + private readonly int _defaultHeaderXf; + private readonly int _defaultDataXf; + + /// Полное имя файла + /// если true, то заголовки растягиваются по ширине текста + public FlexCelXlsFileWriter( + string outputFilePath, + TFileFormats fileFormat, + bool isNeedToFitHeader) + { + _outputFilePath = outputFilePath; + _fileFormat = fileFormat; + _isNeedToFitHeader = isNeedToFitHeader; + + _xls = new XlsFile(1, true); + (_defaultHeaderXf, _defaultDataXf) = _xls.AddDefaultFormats(); + } + + public int AddFormat(FormatSettings formatSettings) + { + var fmt = _xls.GetDefaultFormat; + fmt.Format = formatSettings.DataFormat; + fmt.Font.Size20 = formatSettings.FontSize * 20; + fmt.WrapText = formatSettings.WrapText; + + fmt.HAlignment = formatSettings.TextAlignment switch + { + TextAlignment.Left => THFlxAlignment.left, + TextAlignment.Center => THFlxAlignment.center, + TextAlignment.Right => THFlxAlignment.right, + TextAlignment.Justify => THFlxAlignment.justify, + _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.TextAlignment)) + }; + + fmt.Font.Style = formatSettings.FontStyle switch + { + FontStyle.None => TFlxFontStyles.None, + FontStyle.Bold => TFlxFontStyles.Bold, + FontStyle.Italic => TFlxFontStyles.Italic, + _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.FontStyle)) + }; + + return _xls.AddFormat(fmt); + } + + public int AddDefaultFormat() + { + return _xls.AddFormat(_xls.GetDefaultFormat); + } + + public void AddHeaders(IReadOnlyList data) + { + _headers = data ?? throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + var datum = data[i]; + Append(datum.Value, datum.Format ?? _defaultHeaderXf); + } + + EndLine(); + } + + public void AppendLine(IReadOnlyList data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + var datum = data[i]; + Append(datum.Value, datum.Format); + } + + EndLine(); + } + + public void Append(object? value, int? format = null) + { + _xls.SetCellValue(_currentRow, _currentCell++, value, format ?? _defaultDataXf); + } + + public void EndLine() + { + _currentRow++; + _currentCell = 1; + } + + public void Flush() + { + // подгоним ширину, если надо + if (_isNeedToFitHeader && _headers?.Count > 0) + _xls.AutofitCol(1, _headers.Count, false, 1.1f); + + _xls.Save(_outputFilePath, _fileFormat, ';', Encoding.UTF8); + } + + public void Dispose() + { + // тут нечего освобождать + } +} diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs new file mode 100644 index 0000000..b17d726 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs @@ -0,0 +1,172 @@ +using FlexCel.Core; +using FlexCel.XlsAdapter; +using Microsoft.Extensions.Logging; +using SIISLtd.SSNG.Common; +using SIISLtd.Utils.FileDataReaderWriters.Style; + +namespace SIISLtd.Utils.FileDataReaderWriters +{ + /// + /// Класс для записи звонков в xlsx. Основная фишка - если количество строк больше лимита, то создаются отдельные файлы автоматчиески + /// + public class FlexCelXlsMultiFileWriter : IFileWriter + { + private readonly XlsFile _xls; + private readonly ILogger _logger; + + private IReadOnlyList? _headers; + + private readonly string _savePath; + private readonly string _fileName; + private readonly TFileFormats _fileFormat; + private readonly bool _isNeedToFitHeader; + + private int _currentRow = 1; + private int _currentCell = 1; + private int _partNumber = 1; + private readonly int _defaultHeaderXf; + private readonly int _defaultDataXf; + + /// Имя файла с расширением + /// если true, то заголовки растягиватся по ширине текста + public FlexCelXlsMultiFileWriter( + string savePath, + string fileName, + TFileFormats fileFormat, + bool isNeedToFitHeader, + ILogger logger) + { + if (String.IsNullOrWhiteSpace(savePath)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(savePath)); + if (String.IsNullOrWhiteSpace(fileName)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(fileName)); + + _savePath = savePath; + _fileName = fileName; + _fileFormat = fileFormat; + _isNeedToFitHeader = isNeedToFitHeader; + + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + _xls = new XlsFile(1, true); + (_defaultHeaderXf, _defaultDataXf) = _xls.AddDefaultFormats(); + } + + public int AddFormat(FormatSettings formatSettings) + { + var fmt = _xls.GetDefaultFormat; + fmt.Format = formatSettings.DataFormat; + fmt.Font.Size20 = formatSettings.FontSize * 20; + fmt.WrapText = formatSettings.WrapText; + + fmt.HAlignment = formatSettings.TextAlignment switch + { + TextAlignment.Left => THFlxAlignment.left, + TextAlignment.Center => THFlxAlignment.center, + TextAlignment.Right => THFlxAlignment.right, + TextAlignment.Justify => THFlxAlignment.justify, + _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.TextAlignment)) + }; + + fmt.Font.Style = formatSettings.FontStyle switch + { + FontStyle.None => TFlxFontStyles.None, + FontStyle.Bold => TFlxFontStyles.Bold, + FontStyle.Italic => TFlxFontStyles.Italic, + _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.FontStyle)) + }; + + return _xls.AddFormat(fmt); + } + + public int AddDefaultFormat() + { + return _xls.AddFormat(_xls.GetDefaultFormat); + } + + public void AddHeaders(IReadOnlyList data) + { + _headers = data ?? throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < _headers.Count; i++) + { + var header = _headers[i]; + _xls.SetCellValue(_currentRow, _currentCell++, header.Value, header.Format ?? _defaultHeaderXf); + } + + EndLine(); + } + + public void AppendLine(IReadOnlyList data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + var datum = data[i]; + Append(datum.Value, datum.Format); + } + + EndLine(); + } + + public void Append(object? value, int? format = null) + { + // если новый файл - запишем заголовок + if (_currentRow == 1 && _headers?.Count > 0) + { + for (var i = 0; i < _headers.Count; i++) + { + var header = _headers[i]; + _xls.SetCellValue(_currentRow, _currentCell++, header.Value, header.Format ?? _defaultHeaderXf); + } + + EndLine(); + } + + _xls.SetCellValue(_currentRow, _currentCell++, value, format ?? _defaultDataXf); + } + + public void EndLine() + { + _currentRow++; + _currentCell = 1; + + // если лимит - сбросим данные в файл + if (_currentRow >= ExcelConstants.XlsxRowsMax) + Flush(); + } + + public void Flush() + { + // если ни чего нет - выходим + if (_currentRow == 1) + return; + + // подгоним ширину + if (_isNeedToFitHeader && _headers?.Count > 0) + _xls.AutofitCol(1, _headers.Count, false, 1.1f); + + // сгенерим имя + var fileName = _fileName; + if (_partNumber > 1) + { + fileName = $"{Path.GetFileNameWithoutExtension(_fileName)}_part_{_partNumber}{Path.GetExtension(_fileName)}"; + } + var outputFilePath = Path.Combine(_savePath, fileName); + + // сохраним + _logger.LogDebug($"Сохраняем файл \"{outputFilePath}\"..."); + _xls.Save(outputFilePath, _fileFormat); + _logger.LogInformation($"Файл \"{outputFilePath}\" успешно сохранён"); + + // обнулим состояние + _xls.ClearSheet(); + _partNumber++; + _currentRow = 1; + } + + public void Dispose() + { + // нечего освобождать + } + } +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/IFileWriter.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/IFileWriter.cs new file mode 100644 index 0000000..60b0d8a --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/IFileWriter.cs @@ -0,0 +1,48 @@ +using SIISLtd.Utils.FileDataReaderWriters.Style; + +namespace SIISLtd.Utils.FileDataReaderWriters; + +/// +/// Интерфейс для простого построчного вывода данных +/// +public interface IFileWriter : IDisposable +{ + /// + /// Добавляет формат с указанными настройками + /// + /// + /// + int AddFormat(FormatSettings formatSettings); + + /// + /// Добавляет формат по умолчанию. В Excel он называется "Общий/General" + /// + /// + int AddDefaultFormat(); + + /// + /// Добавляет заголовки таблицы + /// + public void AddHeaders(IReadOnlyList data); + + /// + /// Добавляет массив данных в 1 строку. + /// Автоматически переходит на новую строку + /// + public void AppendLine(IReadOnlyList data); + + /// + /// Добавляет данные в текущую строку без перехода на новую + /// + public void Append(object? value, int? format = null); + + /// + /// Переход на новую строку + /// + public void EndLine(); + + /// + /// Записывает данные из буфера в файл + /// + public void Flush(); +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs new file mode 100644 index 0000000..e0e749d --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs @@ -0,0 +1,192 @@ +using ICSharpCode.SharpZipLib.Zip; +using Microsoft.Extensions.Logging; +using NPOI.SS.UserModel; +using NPOI.XSSF.Streaming; +using SIISLtd.Utils.FileDataReaderWriters.Style; + +namespace SIISLtd.Utils.FileDataReaderWriters; + +/// +/// Класс для записи данных в xlsx / xls формате для NPOI +/// +public class NpoiXlsFileWriter : IFileWriter +{ + private int _currentRow = 0; + private int _currentCell = 0; + private readonly string _outputFilePath; + private readonly ILogger _logger; + + private readonly SXSSFWorkbook _workbook; + private readonly ISheet _sheet; + private readonly ICellStyle _dataStyle; + private FileStream _fileStream; + + private Dictionary _cellStyles = new(); + + /// + /// Конструктор для записи эксель файла через NPOI + /// + /// Адрес итогового файла + /// Количество строк, находящихся в памяти писателя + public NpoiXlsFileWriter(string outputFilePath, ILogger logger, int rowAccessWindowSize = 100) + { + _outputFilePath = outputFilePath; + _logger = logger; + _workbook = new SXSSFWorkbook(rowAccessWindowSize); + _workbook.UseZip64 = UseZip64.On; + _sheet = _workbook.CreateSheet(); + + //настройка формата даты для ячеек + var format = _workbook.CreateDataFormat(); + _dataStyle = _workbook.CreateCellStyle(); + _dataStyle.DataFormat = format.GetFormat("yyyy-MM-dd HH:mm:ss"); + } + + public int AddFormat(FormatSettings formatSettings) + { + var font = _workbook.CreateFont(); + font.IsBold = formatSettings.FontStyle.HasFlag(FontStyle.Bold); + font.IsItalic = formatSettings.FontStyle.HasFlag(FontStyle.Italic); + font.FontHeightInPoints = formatSettings.FontSize; + + var style = _workbook.CreateCellStyle(); + style.SetFont(font); + + style.Alignment = formatSettings.TextAlignment switch + { + TextAlignment.Left => HorizontalAlignment.Left, + TextAlignment.Center => HorizontalAlignment.Center, + TextAlignment.Right => HorizontalAlignment.Right, + TextAlignment.Justify => HorizontalAlignment.Justify, + _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.TextAlignment)) + }; + + style.WrapText = formatSettings.WrapText; + + var format = _workbook.CreateDataFormat(); + style.DataFormat = format.GetFormat(formatSettings.DataFormat); + + var formatNumber = _cellStyles.Count; + _cellStyles.Add(formatNumber, style); + + return formatNumber; + } + + public int AddDefaultFormat() + { + var formatNumber = _cellStyles.Count; + _cellStyles.Add(formatNumber, _workbook.CreateCellStyle()); + + return formatNumber; + } + + public void AddHeaders(IReadOnlyList data) + { + if (data is null) + throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + var datum = data[i]; + Append(datum.Value, datum.Format); + } + + EndLine(); + } + + public void AppendLine(IReadOnlyList data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + var datum = data[i]; + Append(datum.Value, datum.Format); + } + + EndLine(); + } + + public void Append(object? value, int? format = null) + { + if (value is null || (value is string str && String.IsNullOrWhiteSpace(str))) + { + _currentCell++; + return; + } + + var row = _sheet.GetRow(_currentRow) ?? _sheet.CreateRow(_currentRow); + var cell = row.CreateCell(_currentCell); + + switch (value) + { + case byte val: + cell.SetCellValue(val); + break; + case short val: + cell.SetCellValue(val); + break; + case int val: + cell.SetCellValue(val); + break; + case long val: + cell.SetCellValue(val); + break; + case float val: + cell.SetCellValue(val); + break; + case double val: + cell.SetCellValue(val); + break; + case decimal val: + cell.SetCellValue(Convert.ToDouble(val)); + break; + case bool val: + cell.SetCellValue(val); + break; + case IRichTextString val: + cell.SetCellValue(val); + break; + case string val: + cell.SetCellValue(val); + break; + case DateOnly val: + cell.SetCellValue(val); + cell.CellStyle = _dataStyle; + break; + case DateTime val: + cell.SetCellValue(val); + cell.CellStyle = _dataStyle; + break; + default: + _logger.LogWarning("Используем обычный ToString() (Type={Type}, Value={Value})", value.GetType(), value); + cell.SetCellValue(value.ToString()); + break; + } + + if (format is not null) + cell.CellStyle = _cellStyles[(int)format]; + + _currentCell++; + } + + public void EndLine() + { + _currentRow++; + _currentCell = 0; + } + + public void Flush() + { + } + + /// + /// Записываем данные в файл и закрываем стрим. + /// + public void Dispose() + { + _fileStream = File.Open(_outputFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite); + _workbook.Write(_fileStream); + _fileStream.Close(); + } +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs new file mode 100644 index 0000000..ee10df1 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs @@ -0,0 +1,235 @@ +using ICSharpCode.SharpZipLib.Zip; +using Microsoft.Extensions.Logging; +using NPOI.SS.UserModel; +using NPOI.XSSF.Streaming; +using SIISLtd.SSNG.Common; +using SIISLtd.Utils.FileDataReaderWriters.Style; + +namespace SIISLtd.Utils.FileDataReaderWriters; + +/// +/// Класс для записи данных в xlsx / xls формате для NPOI с разбитием на несколько файлов +/// +public class NpoiXlsMultiFileWriter : IFileWriter +{ + private readonly ILogger _logger; + private IReadOnlyList? _headers; + private int _currentRow = 0; + private int _currentCell = 0; + private int _partNumber = 1; + + private readonly SXSSFWorkbook _workbook; + private readonly ICellStyle _dataStyle; + private ISheet _sheet; + private FileStream _fileStream; + + private Dictionary _cellStyles = new(); + + private readonly string _savePath; + private readonly string _fileName; + + /// + /// Конструктор для записи множества эксель файлов через NPOI + /// + /// + /// Название файла + /// Директория сохранения + /// Количество строк, находящихся в памяти писателя + public NpoiXlsMultiFileWriter(string savePath, string fileName, ILogger logger, int rowAccessWindowSize = 100) + { + if (String.IsNullOrWhiteSpace(savePath)) + throw new ArgumentException("Value cannot be null or whitespace.", nameof(savePath)); + if (String.IsNullOrWhiteSpace(fileName)) + throw new ArgumentException("Value cannot be null or whitespace.", nameof(fileName)); + + _savePath = savePath; + _logger = logger; + _fileName = fileName; + _workbook = new SXSSFWorkbook(rowAccessWindowSize); + _workbook.UseZip64 = UseZip64.On; + _sheet = _workbook.CreateSheet(); + + //настройка формата даты для ячеек + var format = _workbook.CreateDataFormat(); + _dataStyle = _workbook.CreateCellStyle(); + _dataStyle.DataFormat = format.GetFormat("yyyy-MM-dd HH:mm:ss"); + } + + public int AddFormat(FormatSettings formatSettings) + { + var font = _workbook.CreateFont(); + font.IsBold = formatSettings.FontStyle.HasFlag(FontStyle.Bold); + font.IsItalic = formatSettings.FontStyle.HasFlag(FontStyle.Italic); + font.FontHeightInPoints = formatSettings.FontSize; + + var style = _workbook.CreateCellStyle(); + style.SetFont(font); + + style.Alignment = formatSettings.TextAlignment switch + { + TextAlignment.Left => HorizontalAlignment.Left, + TextAlignment.Center => HorizontalAlignment.Center, + TextAlignment.Right => HorizontalAlignment.Right, + TextAlignment.Justify => HorizontalAlignment.Justify, + _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.TextAlignment)) + }; + + style.WrapText = formatSettings.WrapText; + + var format = _workbook.CreateDataFormat(); + style.DataFormat = format.GetFormat(formatSettings.DataFormat); + + var formatNumber = _cellStyles.Count; + _cellStyles.Add(formatNumber, style); + + return formatNumber; + } + + public int AddDefaultFormat() + { + var formatNumber = _cellStyles.Count; + _cellStyles.Add(formatNumber, _workbook.CreateCellStyle()); + + return formatNumber; + } + + public void AddHeaders(IReadOnlyList data) + { + _headers = data ?? throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + var datum = data[i]; + Append(datum.Value, datum.Format); + } + + EndLine(); + } + + public void AppendLine(IReadOnlyList data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + + for (var i = 0; i < data.Count; i++) + { + var datum = data[i]; + Append(datum.Value, datum.Format); + } + + EndLine(); + } + + public void Append(object? value, int? format = null) + { + if (value is null || (value is string str && String.IsNullOrWhiteSpace(str))) + { + _currentCell++; + return; + } + + var row = _sheet.GetRow(_currentRow) ?? _sheet.CreateRow(_currentRow); + var cell = row.CreateCell(_currentCell); + + switch (value) + { + case byte val: + cell.SetCellValue(val); + break; + case short val: + cell.SetCellValue(val); + break; + case int val: + cell.SetCellValue(val); + break; + case long val: + cell.SetCellValue(val); + break; + case float val: + cell.SetCellValue(val); + break; + case double val: + cell.SetCellValue(val); + break; + case decimal val: + cell.SetCellValue(Convert.ToDouble(val)); + break; + case bool val: + cell.SetCellValue(val); + break; + case IRichTextString val: + cell.SetCellValue(val); + break; + case string val: + cell.SetCellValue(val); + break; + case DateOnly val: + cell.SetCellValue(val); + cell.CellStyle = _dataStyle; + break; + case DateTime val: + cell.SetCellValue(val); + cell.CellStyle = _dataStyle; + break; + default: + _logger.LogWarning("Используем обычный ToString() (Type={Type}, Value={Value})", value.GetType(), value); + cell.SetCellValue(value.ToString()); + break; + } + + if (format is not null) + cell.CellStyle = _cellStyles[(int)format]; + + _currentCell++; + } + + public void EndLine() + { + _currentRow++; + _currentCell = 0; + + // если лимит - сбросим данные в файл + if (_currentRow >= ExcelConstants.XlsxRowsMax) + Flush(); + } + + public void Flush() + { + // если ничего нет + // или только хедеры и это 2ой файл - выходим + // (первый пустой файл с хедерами - сохраняем) + if (_currentRow == 0 || + (_headers != null && _currentRow == 1 && _partNumber > 1)) + return; + + // сгенерим имя + var fileName = _fileName; + if (_partNumber > 1) + { + fileName = + $"{Path.GetFileNameWithoutExtension(_fileName)}_part_{_partNumber}{Path.GetExtension(_fileName)}"; + } + + var outputFilePath = Path.Combine(_savePath, fileName); + + // сохраним + _logger.LogDebug($"Сохраняем файл \"{outputFilePath}\"..."); + _fileStream = File.Open(outputFilePath, FileMode.OpenOrCreate, FileAccess.Write); + _workbook.Write(_fileStream); + _fileStream.Close(); + _logger.LogInformation($"Файл \"{outputFilePath}\" успешно сохранён"); + + // обнулим состояние + _workbook.RemoveSheetAt(0); + _sheet = _workbook.CreateSheet(); + _partNumber++; + _currentRow = 0; + if (_headers != null) + AddHeaders(_headers); + } + + public void Dispose() + { + if (_fileStream is not null) + Flush(); + } +} \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs new file mode 100644 index 0000000..f6125a6 --- /dev/null +++ b/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs @@ -0,0 +1,20 @@ +using FlexCel.Core; +using FlexCel.XlsAdapter; + +namespace SIISLtd.Utils.FileDataReaderWriters; + +public static class XlsFileExtensions +{ + public static (int HeaderXf, int DataXf) AddDefaultFormats(this XlsFile xls) + { + var fmt = xls.GetDefaultFormat; + fmt.Font.Style = TFlxFontStyles.Bold; + fmt.WrapText = false; + var headerXf = xls.AddFormat(fmt); + + fmt = xls.GetDefaultFormat; + var dataXf = xls.AddFormat(fmt); + + return (headerXf, dataXf); + } +} \ No newline at end of file From fa1dff6ac342b1bd9e66f95875993d39d30247df Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Thu, 1 Feb 2024 19:08:35 +0300 Subject: [PATCH 02/12] rename project --- Curiosity.Utils.sln | 2 +- ...iosity.Utils.FileDataReaderWriters.csproj} | 15 ++-- ....FileDataReaderWriters.csproj.DotSettings} | 0 .../Helpers/ExcelConstants.cs | 29 +++++++ .../Helpers/Guard.cs | 84 +++++++++++++++++++ .../Readers/CsvFileDataReader.cs | 3 +- .../Readers/IFileDataReader.cs | 2 +- .../Readers/XlsFileExtensions.cs | 2 +- .../Readers/XlsxFileDataReader.cs | 12 ++- .../Resources/LNG.cs | 9 +- .../Resources/Strings.en.resx | 0 .../Resources/Strings.resx | 0 .../Style/FontStyle.cs | 2 +- .../Style/FormatSettings.cs | 2 +- .../Style/TextAlignment.cs | 2 +- .../Writers/CellData.cs | 2 +- .../Writers/CsvFileWriter.cs | 10 +-- .../Writers/FlexCelXlsFileWriter.cs | 4 +- .../Writers/FlexCelXlsMultiFileWriter.cs | 9 +- .../Writers/IFileWriter.cs | 4 +- .../Writers/NpoiXlsFileWriter.cs | 6 +- .../Writers/NpoiXlsMultiFileWriter.cs | 8 +- .../Writers/XlsFileExtensions.cs | 2 +- 23 files changed, 159 insertions(+), 50 deletions(-) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj => Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj} (69%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj.DotSettings => Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj.DotSettings} (100%) create mode 100644 src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/ExcelConstants.cs create mode 100644 src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/Guard.cs rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Readers/CsvFileDataReader.cs (98%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Readers/IFileDataReader.cs (96%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Readers/XlsFileExtensions.cs (91%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Readers/XlsxFileDataReader.cs (95%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Resources/LNG.cs (62%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Resources/Strings.en.resx (100%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Resources/Strings.resx (100%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Style/FontStyle.cs (58%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Style/FormatSettings.cs (94%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Style/TextAlignment.cs (61%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/CellData.cs (83%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/CsvFileWriter.cs (87%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/FlexCelXlsFileWriter.cs (97%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/FlexCelXlsMultiFileWriter.cs (96%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/IFileWriter.cs (93%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/NpoiXlsFileWriter.cs (97%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/NpoiXlsMultiFileWriter.cs (97%) rename src/FileData/{SIISLtd.Utils.FileDataReaderWriters => Curiosity.Utils.FileDataReaderWriters}/Writers/XlsFileExtensions.cs (88%) diff --git a/Curiosity.Utils.sln b/Curiosity.Utils.sln index 5372659..c3bb0c1 100644 --- a/Curiosity.Utils.sln +++ b/Curiosity.Utils.sln @@ -151,7 +151,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.SMS.Iqsms", "src\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.SMS.Iqsms.Sample", "samples\Curiosity.SMS.Iqsms.Sample\Curiosity.SMS.Iqsms.Sample.csproj", "{4015E00D-EC76-4A73-A52F-4C4D71C6B8B5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SIISLtd.Utils.FileDataReaderWriters", "src\FileData\SIISLtd.Utils.FileDataReaderWriters\SIISLtd.Utils.FileDataReaderWriters.csproj", "{D135ADFA-0A52-41C0-876F-691876A780E1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.Utils.FileDataReaderWriters", "src\FileData\Curiosity.Utils.FileDataReaderWriters\Curiosity.Utils.FileDataReaderWriters.csproj", "{D135ADFA-0A52-41C0-876F-691876A780E1}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileData", "FileData", "{2B8CCF93-24F0-45F9-9961-85695351141E}" EndProject diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj similarity index 69% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj index 4d10c4a..780b34c 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj @@ -8,20 +8,23 @@ + + + + + + + + + $(NoWarn);1591 $(NoWarn);1573 - - - - - - diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj.DotSettings b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj.DotSettings similarity index 100% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/SIISLtd.Utils.FileDataReaderWriters.csproj.DotSettings rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj.DotSettings diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/ExcelConstants.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/ExcelConstants.cs new file mode 100644 index 0000000..a356b27 --- /dev/null +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/ExcelConstants.cs @@ -0,0 +1,29 @@ +namespace Curiosity.Utils.FileDataReaderWriters.Helpers; + +public static class ExcelConstants +{ + /// + /// Максимальное число строк в XLSX файле + /// + public const int XlsxRowsMax = 1048576; + + /// + /// Максимальное число колонок в XLSX файле + /// + public const int XlsxColMax = 16384; + + /// + /// Максимальное число строк в XLS файле + /// + public const int XlsRowsMax = 65536; + + /// + /// Максимальное число колонок в XLS файле + /// + public const int XlsColMax = 256; + + /// + /// Максимальное количество символов вмещающееся в ячейку + /// + public const int MaxCellLength = 32759; +} \ No newline at end of file diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/Guard.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/Guard.cs new file mode 100644 index 0000000..c7218c2 --- /dev/null +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/Guard.cs @@ -0,0 +1,84 @@ +using System.Runtime.CompilerServices; + +namespace Curiosity.Utils.FileDataReaderWriters; + +public static partial class Guard + { + /// + /// Проверяет, что параметр не null. + /// + /// Значение параметра. + /// Название параметра. + /// Тип параметра. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotNull(T? parameter, string parameterName) where T: class + { + if (parameter == null) + throw new ArgumentNullException(parameterName); + } + + /// + /// Проверяет, что параметр не null. + /// + /// Значение параметра. + /// Название параметра. + /// Тип параметра. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertHasValue(Nullable parameter, string parameterName) where T: struct + { + if (!parameter.HasValue) + throw new ArgumentNullException(parameterName); + } + + /// + /// Проверяет, что строка не пустая. + /// + /// Значение параметра + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotEmpty(string? parameter, string parameterName) + { + if (String.IsNullOrWhiteSpace(parameter)) + throw new ArgumentNullException(parameterName); + } + + /// + /// Проверяет, что значение находится в заданном диапазоне. + /// + /// Значение параметра + /// Минимальное допустимое значение + /// Максимальное допустимое значение + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertInRange(int parameter, int minValue, int maxValue, string parameterName) + { + if (parameter < minValue || parameter > maxValue) + throw new ArgumentOutOfRangeException(parameterName); + } + + /// + /// Проверяет, что значение не отрицательно. + /// + /// Значение параметра + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotNegative(int? parameter, string parameterName) + { + if (!parameter.HasValue) return; + AssertNotNegative(parameter.Value, parameterName); + } + + /// + /// Проверяет, что значение не отрицательно. + /// + /// Значение параметра + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotNegative(int parameter, string parameterName) + { + if (parameter < 0) + throw new ArgumentOutOfRangeException(parameterName); + } + } \ No newline at end of file diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs similarity index 98% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs index b6f2936..42d12b1 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs @@ -1,8 +1,7 @@ using System.Text; -using SIISLtd.SSNG.Common.Guards; using Sylvan.Data.Csv; -namespace SIISLtd.Utils.FileDataReaderWriters.Readers; +namespace Curiosity.Utils.FileDataReaderWriters.Readers; /// /// Класс для построчного чтения CSV файлов. diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs similarity index 96% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs index fc1477c..4a36c44 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs @@ -1,4 +1,4 @@ -namespace SIISLtd.Utils.FileDataReaderWriters.Readers; +namespace Curiosity.Utils.FileDataReaderWriters.Readers; /// /// Общий интерфейс для классов, которые читает загруженные файлы построчно. diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs similarity index 91% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs index 9a1fbce..5e2a06d 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs @@ -1,6 +1,6 @@ using FlexCel.XlsAdapter; -namespace SIISLtd.Utils.FileDataReaderWriters.Readers +namespace Curiosity.Utils.FileDataReaderWriters.Readers { /// /// Методы расширения для в TMS FlexCell diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs similarity index 95% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs index c8a51f4..a13aa55 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs @@ -1,11 +1,9 @@ -using FlexCel.Core; +using Curiosity.Utils.FileDataReaderWriters.Helpers; +using Curiosity.Utils.FileDataReaderWriters.Resources; +using FlexCel.Core; using FlexCel.XlsAdapter; -using SIISLtd.SSNG.Common; -using SIISLtd.SSNG.Common.Guards; -using SIISLtd.SSNG.Exceptions; -using SIISLtd.Utils.FileDataReaderWriters.Resources; -namespace SIISLtd.Utils.FileDataReaderWriters.Readers; +namespace Curiosity.Utils.FileDataReaderWriters.Readers; /// /// Класс для построчного чтения данных их Xlsx/xlsx файлов. @@ -122,7 +120,7 @@ public static XlsxFileDataReader CreateReader( // выбираем первый лист if (xls.SheetCount < 1) - throw new UserException(LNG.Get("Файл должен содержать хотя бы один лист")); + throw new ArgumentException(LNG.Get("Файл должен содержать хотя бы один лист")); xls.ActiveSheet = 1; diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/LNG.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/LNG.cs similarity index 62% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/LNG.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/LNG.cs index 81dcc54..46901aa 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/LNG.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/LNG.cs @@ -1,7 +1,7 @@ using System.Globalization; -using SIISLtd.Utils.Localization; +using Curiosity.Localization; -namespace SIISLtd.Utils.FileDataReaderWriters.Resources +namespace Curiosity.Utils.FileDataReaderWriters.Resources { internal static class LNG { @@ -18,10 +18,5 @@ public static string Get(string source, params object[] arguments) { return Localizer.Get(Options.Prefix, source, false, arguments); } - - public static string GetForCulture(CultureInfo culture, string source, params object[] arguments) - { - return Localizer.GetForCulture(culture, Options.Prefix, source, false, arguments); - } } } diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.en.resx b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.en.resx similarity index 100% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.en.resx rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.en.resx diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.resx b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.resx similarity index 100% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Resources/Strings.resx rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.resx diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FontStyle.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FontStyle.cs similarity index 58% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FontStyle.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FontStyle.cs index 0c75ba2..f887baa 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FontStyle.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FontStyle.cs @@ -1,4 +1,4 @@ -namespace SIISLtd.Utils.FileDataReaderWriters.Style; +namespace Curiosity.Utils.FileDataReaderWriters.Style; [Flags] public enum FontStyle diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FormatSettings.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FormatSettings.cs similarity index 94% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FormatSettings.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FormatSettings.cs index b08a721..2f98d95 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/FormatSettings.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FormatSettings.cs @@ -1,4 +1,4 @@ -namespace SIISLtd.Utils.FileDataReaderWriters.Style; +namespace Curiosity.Utils.FileDataReaderWriters.Style; /// /// Настройки формата ячеек diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/TextAlignment.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/TextAlignment.cs similarity index 61% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/TextAlignment.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/TextAlignment.cs index e1fd71a..7dc6fef 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Style/TextAlignment.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/TextAlignment.cs @@ -1,4 +1,4 @@ -namespace SIISLtd.Utils.FileDataReaderWriters.Style; +namespace Curiosity.Utils.FileDataReaderWriters.Style; public enum TextAlignment { diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CellData.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CellData.cs similarity index 83% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CellData.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CellData.cs index f8cf211..1c4b7f9 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CellData.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CellData.cs @@ -1,4 +1,4 @@ -namespace SIISLtd.Utils.FileDataReaderWriters; +namespace Curiosity.Utils.FileDataReaderWriters.Writers; /// /// Данные ячейки с форматом diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs similarity index 87% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs index 8bb998b..4bf3fd9 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs @@ -1,11 +1,11 @@ +using System.Globalization; using System.Text; using CsvHelper; using CsvHelper.Configuration; -using FlexCel.Core; -using SIISLtd.Utils.FileDataReaderWriters.Style; -using SIISLtd.Utils.Tools.Localization; +using Curiosity.Utils.FileDataReaderWriters.Style; +using Curiosity.Utils.FileDataReaderWriters.Writers; -namespace SIISLtd.Utils.FileDataReaderWriters; +namespace Curiosity.Utils.FileDataReaderWriters; /// /// Запись данных в .csv формате @@ -20,7 +20,7 @@ public class CsvFileWriter : IFileWriter public CsvFileWriter(string outputFilePath) { - var configuration = new CsvConfiguration(LngHelper.CurrentCulture) + var configuration = new CsvConfiguration(CultureInfo.CurrentCulture) { Delimiter = ";", Mode = CsvMode.RFC4180, diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs similarity index 97% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs index 3cf5a31..be73a8f 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs @@ -1,9 +1,9 @@ using System.Text; +using Curiosity.Utils.FileDataReaderWriters.Style; using FlexCel.Core; using FlexCel.XlsAdapter; -using SIISLtd.Utils.FileDataReaderWriters.Style; -namespace SIISLtd.Utils.FileDataReaderWriters; +namespace Curiosity.Utils.FileDataReaderWriters.Writers; /// /// Запись данных в xlsx / xls формате diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs similarity index 96% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs index b17d726..7300ae7 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs @@ -1,10 +1,11 @@ -using FlexCel.Core; +using Curiosity.Utils.FileDataReaderWriters.Helpers; +using Curiosity.Utils.FileDataReaderWriters.Style; +using Curiosity.Utils.FileDataReaderWriters.Writers; +using FlexCel.Core; using FlexCel.XlsAdapter; using Microsoft.Extensions.Logging; -using SIISLtd.SSNG.Common; -using SIISLtd.Utils.FileDataReaderWriters.Style; -namespace SIISLtd.Utils.FileDataReaderWriters +namespace Curiosity.Utils.FileDataReaderWriters { /// /// Класс для записи звонков в xlsx. Основная фишка - если количество строк больше лимита, то создаются отдельные файлы автоматчиески diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/IFileWriter.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/IFileWriter.cs similarity index 93% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/IFileWriter.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/IFileWriter.cs index 60b0d8a..9db5eba 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/IFileWriter.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/IFileWriter.cs @@ -1,6 +1,6 @@ -using SIISLtd.Utils.FileDataReaderWriters.Style; +using Curiosity.Utils.FileDataReaderWriters.Style; -namespace SIISLtd.Utils.FileDataReaderWriters; +namespace Curiosity.Utils.FileDataReaderWriters.Writers; /// /// Интерфейс для простого построчного вывода данных diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs similarity index 97% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs index e0e749d..83e0ca3 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs @@ -1,10 +1,10 @@ -using ICSharpCode.SharpZipLib.Zip; +using Curiosity.Utils.FileDataReaderWriters.Style; +using ICSharpCode.SharpZipLib.Zip; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; using NPOI.XSSF.Streaming; -using SIISLtd.Utils.FileDataReaderWriters.Style; -namespace SIISLtd.Utils.FileDataReaderWriters; +namespace Curiosity.Utils.FileDataReaderWriters.Writers; /// /// Класс для записи данных в xlsx / xls формате для NPOI diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs similarity index 97% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs index ee10df1..914d8d3 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs @@ -1,11 +1,11 @@ -using ICSharpCode.SharpZipLib.Zip; +using Curiosity.Utils.FileDataReaderWriters.Helpers; +using Curiosity.Utils.FileDataReaderWriters.Style; +using ICSharpCode.SharpZipLib.Zip; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; using NPOI.XSSF.Streaming; -using SIISLtd.SSNG.Common; -using SIISLtd.Utils.FileDataReaderWriters.Style; -namespace SIISLtd.Utils.FileDataReaderWriters; +namespace Curiosity.Utils.FileDataReaderWriters.Writers; /// /// Класс для записи данных в xlsx / xls формате для NPOI с разбитием на несколько файлов diff --git a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs similarity index 88% rename from src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs rename to src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs index f6125a6..2d65e94 100644 --- a/src/FileData/SIISLtd.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs +++ b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs @@ -1,7 +1,7 @@ using FlexCel.Core; using FlexCel.XlsAdapter; -namespace SIISLtd.Utils.FileDataReaderWriters; +namespace Curiosity.Utils.FileDataReaderWriters.Writers; public static class XlsFileExtensions { From dba1b9bf3b6c3a4545768c60e970742c5fedf558 Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Thu, 1 Feb 2024 19:17:55 +0300 Subject: [PATCH 03/12] rename project --- Curiosity.Utils.sln | 5 ++++- .../Curiosity.FileDataReaderWriters.csproj} | 0 .../Helpers/ExcelConstants.cs | 2 +- .../Helpers/Guard.cs | 2 +- .../Readers/CsvFileDataReader.cs | 2 +- .../Readers/IFileDataReader.cs | 2 +- .../Readers/XlsFileExtensions.cs | 2 +- .../Readers/XlsxFileDataReader.cs | 6 +++--- .../Resources/LNG.cs | 2 +- .../Resources/Strings.en.resx | 0 .../Resources/Strings.resx | 0 .../Style/FontStyle.cs | 2 +- .../Style/FormatSettings.cs | 2 +- .../Style/TextAlignment.cs | 2 +- .../Writers/CellData.cs | 2 +- .../Writers/CsvFileWriter.cs | 6 +++--- .../Writers/FlexCelXlsFileWriter.cs | 4 ++-- .../Writers/FlexCelXlsMultiFileWriter.cs | 8 ++++---- .../Writers/IFileWriter.cs | 4 ++-- .../Writers/NpoiXlsFileWriter.cs | 4 ++-- .../Writers/NpoiXlsMultiFileWriter.cs | 6 +++--- .../Writers/XlsFileExtensions.cs | 2 +- ...riosity.Utils.FileDataReaderWriters.csproj.DotSettings | 2 -- 23 files changed, 34 insertions(+), 33 deletions(-) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj => Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj} (100%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Helpers/ExcelConstants.cs (93%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Helpers/Guard.cs (98%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Readers/CsvFileDataReader.cs (99%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Readers/IFileDataReader.cs (96%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Readers/XlsFileExtensions.cs (91%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Readers/XlsxFileDataReader.cs (97%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Resources/LNG.cs (90%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Resources/Strings.en.resx (100%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Resources/Strings.resx (100%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Style/FontStyle.cs (58%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Style/FormatSettings.cs (94%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Style/TextAlignment.cs (61%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/CellData.cs (83%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/CsvFileWriter.cs (92%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/FlexCelXlsFileWriter.cs (97%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/FlexCelXlsMultiFileWriter.cs (96%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/IFileWriter.cs (93%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/NpoiXlsFileWriter.cs (98%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/NpoiXlsMultiFileWriter.cs (97%) rename src/FileData/{Curiosity.Utils.FileDataReaderWriters => Curiosity.FileDataReaderWriters}/Writers/XlsFileExtensions.cs (88%) delete mode 100644 src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj.DotSettings diff --git a/Curiosity.Utils.sln b/Curiosity.Utils.sln index c3bb0c1..2f9820e 100644 --- a/Curiosity.Utils.sln +++ b/Curiosity.Utils.sln @@ -151,10 +151,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.SMS.Iqsms", "src\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.SMS.Iqsms.Sample", "samples\Curiosity.SMS.Iqsms.Sample\Curiosity.SMS.Iqsms.Sample.csproj", "{4015E00D-EC76-4A73-A52F-4C4D71C6B8B5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.Utils.FileDataReaderWriters", "src\FileData\Curiosity.Utils.FileDataReaderWriters\Curiosity.Utils.FileDataReaderWriters.csproj", "{D135ADFA-0A52-41C0-876F-691876A780E1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters", "src\FileData\Curiosity.FileDataReaderWriters\Curiosity.FileDataReaderWriters.csproj", "{D135ADFA-0A52-41C0-876F-691876A780E1}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileData", "FileData", "{2B8CCF93-24F0-45F9-9961-85695351141E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileData", "FileData", "{973E81A0-574E-406A-AB95-01B1243A984C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -424,6 +426,7 @@ Global {4015E00D-EC76-4A73-A52F-4C4D71C6B8B5} = {A7A87B49-2E4C-4A0A-92F4-7C7849F36A84} {2B8CCF93-24F0-45F9-9961-85695351141E} = {7C485CBA-A08F-4A0E-835A-4505CBBB7EA8} {D135ADFA-0A52-41C0-876F-691876A780E1} = {2B8CCF93-24F0-45F9-9961-85695351141E} + {973E81A0-574E-406A-AB95-01B1243A984C} = {55CC9AE1-6978-4ECB-9A0A-0DCE1B66D492} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BA1A20A2-0D4E-492D-877C-0A36F18FBFF1} diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj similarity index 100% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj rename to src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/ExcelConstants.cs b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/ExcelConstants.cs similarity index 93% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/ExcelConstants.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Helpers/ExcelConstants.cs index a356b27..796f4ad 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/ExcelConstants.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/ExcelConstants.cs @@ -1,4 +1,4 @@ -namespace Curiosity.Utils.FileDataReaderWriters.Helpers; +namespace Curiosity.FileDataReaderWriters.Helpers; public static class ExcelConstants { diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/Guard.cs b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs similarity index 98% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/Guard.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs index c7218c2..8721218 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Helpers/Guard.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs @@ -1,6 +1,6 @@ using System.Runtime.CompilerServices; -namespace Curiosity.Utils.FileDataReaderWriters; +namespace Curiosity.FileDataReaderWriters; public static partial class Guard { diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs similarity index 99% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs index 42d12b1..5141d9c 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/CsvFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs @@ -1,7 +1,7 @@ using System.Text; using Sylvan.Data.Csv; -namespace Curiosity.Utils.FileDataReaderWriters.Readers; +namespace Curiosity.FileDataReaderWriters.Readers; /// /// Класс для построчного чтения CSV файлов. diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/IFileDataReader.cs similarity index 96% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Readers/IFileDataReader.cs index 4a36c44..32be21a 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/IFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/IFileDataReader.cs @@ -1,4 +1,4 @@ -namespace Curiosity.Utils.FileDataReaderWriters.Readers; +namespace Curiosity.FileDataReaderWriters.Readers; /// /// Общий интерфейс для классов, которые читает загруженные файлы построчно. diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs similarity index 91% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs index 5e2a06d..a0b4ca0 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsFileExtensions.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs @@ -1,6 +1,6 @@ using FlexCel.XlsAdapter; -namespace Curiosity.Utils.FileDataReaderWriters.Readers +namespace Curiosity.FileDataReaderWriters.Readers { /// /// Методы расширения для в TMS FlexCell diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs similarity index 97% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs index a13aa55..0cd107f 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Readers/XlsxFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs @@ -1,9 +1,9 @@ -using Curiosity.Utils.FileDataReaderWriters.Helpers; -using Curiosity.Utils.FileDataReaderWriters.Resources; +using Curiosity.FileDataReaderWriters.Helpers; +using Curiosity.FileDataReaderWriters.Resources; using FlexCel.Core; using FlexCel.XlsAdapter; -namespace Curiosity.Utils.FileDataReaderWriters.Readers; +namespace Curiosity.FileDataReaderWriters.Readers; /// /// Класс для построчного чтения данных их Xlsx/xlsx файлов. diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/LNG.cs b/src/FileData/Curiosity.FileDataReaderWriters/Resources/LNG.cs similarity index 90% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/LNG.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Resources/LNG.cs index 46901aa..5f536d9 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/LNG.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Resources/LNG.cs @@ -1,7 +1,7 @@ using System.Globalization; using Curiosity.Localization; -namespace Curiosity.Utils.FileDataReaderWriters.Resources +namespace Curiosity.FileDataReaderWriters.Resources { internal static class LNG { diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.en.resx b/src/FileData/Curiosity.FileDataReaderWriters/Resources/Strings.en.resx similarity index 100% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.en.resx rename to src/FileData/Curiosity.FileDataReaderWriters/Resources/Strings.en.resx diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.resx b/src/FileData/Curiosity.FileDataReaderWriters/Resources/Strings.resx similarity index 100% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Resources/Strings.resx rename to src/FileData/Curiosity.FileDataReaderWriters/Resources/Strings.resx diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FontStyle.cs b/src/FileData/Curiosity.FileDataReaderWriters/Style/FontStyle.cs similarity index 58% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FontStyle.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Style/FontStyle.cs index f887baa..0ae36a4 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FontStyle.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Style/FontStyle.cs @@ -1,4 +1,4 @@ -namespace Curiosity.Utils.FileDataReaderWriters.Style; +namespace Curiosity.FileDataReaderWriters.Style; [Flags] public enum FontStyle diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FormatSettings.cs b/src/FileData/Curiosity.FileDataReaderWriters/Style/FormatSettings.cs similarity index 94% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FormatSettings.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Style/FormatSettings.cs index 2f98d95..1ce426a 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/FormatSettings.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Style/FormatSettings.cs @@ -1,4 +1,4 @@ -namespace Curiosity.Utils.FileDataReaderWriters.Style; +namespace Curiosity.FileDataReaderWriters.Style; /// /// Настройки формата ячеек diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/TextAlignment.cs b/src/FileData/Curiosity.FileDataReaderWriters/Style/TextAlignment.cs similarity index 61% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/TextAlignment.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Style/TextAlignment.cs index 7dc6fef..43355e2 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Style/TextAlignment.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Style/TextAlignment.cs @@ -1,4 +1,4 @@ -namespace Curiosity.Utils.FileDataReaderWriters.Style; +namespace Curiosity.FileDataReaderWriters.Style; public enum TextAlignment { diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CellData.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/CellData.cs similarity index 83% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CellData.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/CellData.cs index 1c4b7f9..0d1d2f5 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CellData.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/CellData.cs @@ -1,4 +1,4 @@ -namespace Curiosity.Utils.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Writers; /// /// Данные ячейки с форматом diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs similarity index 92% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs index 4bf3fd9..799e76c 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/CsvFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs @@ -2,10 +2,10 @@ using System.Text; using CsvHelper; using CsvHelper.Configuration; -using Curiosity.Utils.FileDataReaderWriters.Style; -using Curiosity.Utils.FileDataReaderWriters.Writers; +using Curiosity.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Writers; -namespace Curiosity.Utils.FileDataReaderWriters; +namespace Curiosity.FileDataReaderWriters; /// /// Запись данных в .csv формате diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs similarity index 97% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs index be73a8f..eaa6c62 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs @@ -1,9 +1,9 @@ using System.Text; -using Curiosity.Utils.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Style; using FlexCel.Core; using FlexCel.XlsAdapter; -namespace Curiosity.Utils.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Writers; /// /// Запись данных в xlsx / xls формате diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs similarity index 96% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs index 7300ae7..7d741a5 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs @@ -1,11 +1,11 @@ -using Curiosity.Utils.FileDataReaderWriters.Helpers; -using Curiosity.Utils.FileDataReaderWriters.Style; -using Curiosity.Utils.FileDataReaderWriters.Writers; +using Curiosity.FileDataReaderWriters.Helpers; +using Curiosity.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Writers; using FlexCel.Core; using FlexCel.XlsAdapter; using Microsoft.Extensions.Logging; -namespace Curiosity.Utils.FileDataReaderWriters +namespace Curiosity.FileDataReaderWriters { /// /// Класс для записи звонков в xlsx. Основная фишка - если количество строк больше лимита, то создаются отдельные файлы автоматчиески diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/IFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/IFileWriter.cs similarity index 93% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/IFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/IFileWriter.cs index 9db5eba..a1ba801 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/IFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/IFileWriter.cs @@ -1,6 +1,6 @@ -using Curiosity.Utils.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Style; -namespace Curiosity.Utils.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Writers; /// /// Интерфейс для простого построчного вывода данных diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs similarity index 98% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs index 83e0ca3..aad7d83 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs @@ -1,10 +1,10 @@ -using Curiosity.Utils.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Style; using ICSharpCode.SharpZipLib.Zip; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; using NPOI.XSSF.Streaming; -namespace Curiosity.Utils.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Writers; /// /// Класс для записи данных в xlsx / xls формате для NPOI diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs similarity index 97% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs index 914d8d3..64de85b 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs @@ -1,11 +1,11 @@ -using Curiosity.Utils.FileDataReaderWriters.Helpers; -using Curiosity.Utils.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Helpers; +using Curiosity.FileDataReaderWriters.Style; using ICSharpCode.SharpZipLib.Zip; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; using NPOI.XSSF.Streaming; -namespace Curiosity.Utils.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Writers; /// /// Класс для записи данных в xlsx / xls формате для NPOI с разбитием на несколько файлов diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/XlsFileExtensions.cs similarity index 88% rename from src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs rename to src/FileData/Curiosity.FileDataReaderWriters/Writers/XlsFileExtensions.cs index 2d65e94..e4d5d3a 100644 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Writers/XlsFileExtensions.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/XlsFileExtensions.cs @@ -1,7 +1,7 @@ using FlexCel.Core; using FlexCel.XlsAdapter; -namespace Curiosity.Utils.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Writers; public static class XlsFileExtensions { diff --git a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj.DotSettings b/src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj.DotSettings deleted file mode 100644 index 0b1e95c..0000000 --- a/src/FileData/Curiosity.Utils.FileDataReaderWriters/Curiosity.Utils.FileDataReaderWriters.csproj.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - False \ No newline at end of file From 106f6fbc21a07ffb126840e31bc66ce243a0fbb8 Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Thu, 1 Feb 2024 19:29:54 +0300 Subject: [PATCH 04/12] add tests --- Curiosity.Utils.sln | 7 ++ ...ity.FileDataReaderWriters.UnitTests.csproj | 30 +++++ .../NpoiXlsFileWriter_Should.cs | 86 ++++++++++++++ .../NpoiXlsMultiFileWriter_Should.cs | 111 ++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj create mode 100644 tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs create mode 100644 tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs diff --git a/Curiosity.Utils.sln b/Curiosity.Utils.sln index 2f9820e..897bd7a 100644 --- a/Curiosity.Utils.sln +++ b/Curiosity.Utils.sln @@ -157,6 +157,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileData", "FileData", "{2B EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileData", "FileData", "{973E81A0-574E-406A-AB95-01B1243A984C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.UnitTests", "tests\UnitTests\Curiosity.FileDataReaderWriters.UnitTests\Curiosity.FileDataReaderWriters.UnitTests.csproj", "{14444441-9159-44B1-AEE0-50B9C8F6E90C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -351,6 +353,10 @@ Global {D135ADFA-0A52-41C0-876F-691876A780E1}.Debug|Any CPU.Build.0 = Debug|Any CPU {D135ADFA-0A52-41C0-876F-691876A780E1}.Release|Any CPU.ActiveCfg = Release|Any CPU {D135ADFA-0A52-41C0-876F-691876A780E1}.Release|Any CPU.Build.0 = Release|Any CPU + {14444441-9159-44B1-AEE0-50B9C8F6E90C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14444441-9159-44B1-AEE0-50B9C8F6E90C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14444441-9159-44B1-AEE0-50B9C8F6E90C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14444441-9159-44B1-AEE0-50B9C8F6E90C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -427,6 +433,7 @@ Global {2B8CCF93-24F0-45F9-9961-85695351141E} = {7C485CBA-A08F-4A0E-835A-4505CBBB7EA8} {D135ADFA-0A52-41C0-876F-691876A780E1} = {2B8CCF93-24F0-45F9-9961-85695351141E} {973E81A0-574E-406A-AB95-01B1243A984C} = {55CC9AE1-6978-4ECB-9A0A-0DCE1B66D492} + {14444441-9159-44B1-AEE0-50B9C8F6E90C} = {973E81A0-574E-406A-AB95-01B1243A984C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BA1A20A2-0D4E-492D-877C-0A36F18FBFF1} diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj new file mode 100644 index 0000000..a18fd5f --- /dev/null +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj @@ -0,0 +1,30 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs new file mode 100644 index 0000000..b8616e0 --- /dev/null +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs @@ -0,0 +1,86 @@ +using Curiosity.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Writers; +using Microsoft.Extensions.Logging; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using Xunit; + +namespace Curiosity.FileDataReaderWriters.UnitTests +{ + /// + /// Тесты записи для NPOI + /// + public class NpoiXlsFileWriter_Should + { + [Fact] + public void WriteWithHeaders() + { + //ARRANGE + var fileName = "testFile.xlsx"; + var header1 = "Header1"; + var header2 = "Header2"; + var header3 = "Header3"; + var headerFormat = new FormatSettings() + { + FontSize = 20, + FontStyle = FontStyle.Bold, + TextAlignment = TextAlignment.Center, + DataFormat = "@" + }; + + var logger = new Logger(new LoggerFactory()); + var fileWriter = new NpoiXlsFileWriter(fileName, logger); + var formatNumber = fileWriter.AddFormat(headerFormat); + + var headers = new List(); + headers.Add(new CellData(header1, formatNumber)); + headers.Add(new CellData(header2)); + headers.Add(new CellData(header3, formatNumber)); + + var firstRow = new List(); + firstRow.Add(new CellData(1.23)); + firstRow.Add(new CellData(DateTime.Now)); + firstRow.Add(new CellData("blabla")); + firstRow.Add(new CellData(null)); + + var secondRow = new List(); + secondRow.Add(new CellData(3.43)); + secondRow.Add(new CellData(DateTime.UtcNow)); + secondRow.Add(new CellData("blabla2")); + + //ACT + fileWriter.AddHeaders(headers); + fileWriter.AppendLine(firstRow); + fileWriter.AppendLine(secondRow); + fileWriter.Dispose(); + + //ASSERT + try + { + var stream = File.Open(fileName, FileMode.Open, FileAccess.Read); + var fileReader = new XSSFWorkbook(stream); + var sheet = fileReader.GetSheetAt(0); + + var headersResult = sheet.GetRow(0); + Assert.Equal(headersResult.GetCell(0).StringCellValue, header1); + Assert.Equal(headersResult.GetCell(1).StringCellValue, header2); + Assert.Equal(headersResult.GetCell(2).StringCellValue, header3); + Assert.Equal(headersResult.GetCell(0).CellStyle.Alignment, HorizontalAlignment.Center); + Assert.Equal(headersResult.GetCell(2).CellStyle.GetDataFormatString(), headerFormat.DataFormat); + + var firstRowResult = sheet.GetRow(1); + Assert.Equal(firstRowResult.GetCell(0).NumericCellValue, firstRow[0].Value); + Assert.Equal(firstRowResult.GetCell(1).DateCellValue.ToLongDateString(), DateTime.Parse(firstRow[1].Value.ToString()).ToLongDateString()); + Assert.Equal(firstRowResult.GetCell(2).StringCellValue, firstRow[2].Value); + + var secondRowResult = sheet.GetRow(2); + Assert.Equal(secondRowResult.GetCell(0).NumericCellValue, secondRow[0].Value); + Assert.Equal(secondRowResult.GetCell(1).DateCellValue.ToLongDateString(), DateTime.Parse(secondRow[1].Value.ToString()).ToLongDateString()); + Assert.Equal(secondRowResult.GetCell(2).StringCellValue, secondRow[2].Value); + } + finally{ + File.Delete(fileName); + } + } + } +} \ No newline at end of file diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs new file mode 100644 index 0000000..acd84a2 --- /dev/null +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs @@ -0,0 +1,111 @@ +using Curiosity.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Writers; +using Microsoft.Extensions.Logging; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using Xunit; + +namespace Curiosity.FileDataReaderWriters.UnitTests +{ + /// + /// Тесты записи для NPOI + /// + public class NpoiXlsMultiFileWriter_Should + { + [Fact] + public void WriteWithHeaders() + { + //ARRANGE + var fileName = "testFile.xlsx"; + var header1 = "Header1"; + var header2 = "Header2"; + var header3 = "Header3"; + var headerFormat = new FormatSettings() + { + FontSize = 20, + FontStyle = FontStyle.Bold, + TextAlignment = TextAlignment.Center, + DataFormat = "@" + }; + + var logger = new Logger(new LoggerFactory()); + var fileWriter = new NpoiXlsMultiFileWriter(Directory.GetCurrentDirectory(), fileName, logger); + var formatNumber = fileWriter.AddFormat(headerFormat); + + var headers = new List(); + headers.Add(new CellData(header1, formatNumber)); + headers.Add(new CellData(header2)); + headers.Add(new CellData(header3, formatNumber)); + + var firstRow = new List(); + firstRow.Add(new CellData(1.23)); + firstRow.Add(new CellData(DateTime.Now)); + firstRow.Add(new CellData("blabla")); + firstRow.Add(new CellData(null)); + + var secondRow = new List(); + secondRow.Add(new CellData(3.43)); + secondRow.Add(new CellData(DateTime.UtcNow)); + secondRow.Add(new CellData("blabla2")); + + var secondFileData = Enumerable.Range(0, 1100000).Select(x => new CellData((double)x)); + + //ACT + fileWriter.AddHeaders(headers); + fileWriter.AppendLine(firstRow); + fileWriter.AppendLine(secondRow); + foreach (var data in secondFileData) + { + fileWriter.Append(data.Value); + fileWriter.EndLine(); + } + + fileWriter.Dispose(); + + //ASSERT + try + { + var stream = File.Open(fileName, FileMode.Open, FileAccess.Read); + var fileReader = new XSSFWorkbook(stream); + var sheet = fileReader.GetSheetAt(0); + + var headersResult = sheet.GetRow(0); + Assert.Equal(headersResult.GetCell(0).StringCellValue, header1); + Assert.Equal(headersResult.GetCell(1).StringCellValue, header2); + Assert.Equal(headersResult.GetCell(2).StringCellValue, header3); + Assert.Equal(headersResult.GetCell(0).CellStyle.Alignment, HorizontalAlignment.Center); + Assert.Equal(headersResult.GetCell(2).CellStyle.GetDataFormatString(), headerFormat.DataFormat); + + var firstRowResult = sheet.GetRow(1); + Assert.Equal(firstRowResult.GetCell(0).NumericCellValue, firstRow[0].Value); + Assert.Equal(firstRowResult.GetCell(1).DateCellValue.ToLongDateString(), DateTime.Parse(firstRow[1].Value.ToString()).ToLongDateString()); + Assert.Equal(firstRowResult.GetCell(2).StringCellValue, firstRow[2].Value); + + var secondRowResult = sheet.GetRow(2); + Assert.Equal(secondRowResult.GetCell(0).NumericCellValue, secondRow[0].Value); + Assert.Equal(secondRowResult.GetCell(1).DateCellValue.ToLongDateString(), DateTime.Parse(secondRow[1].Value.ToString()).ToLongDateString()); + Assert.Equal(secondRowResult.GetCell(2).StringCellValue, secondRow[2].Value); + + stream.Close(); + + var streamPart2 = File.Open($"{Path.GetFileNameWithoutExtension(fileName)}_part_2.xlsx", FileMode.Open, FileAccess.Read); + + var fileReaderPart2 = new XSSFWorkbook(streamPart2); + var sheetPart2 = fileReaderPart2.GetSheetAt(0); + + var headersResultPart2 = sheetPart2.GetRow(0); + Assert.Equal(headersResultPart2.GetCell(0).StringCellValue, header1); + Assert.Equal(headersResultPart2.GetCell(1).StringCellValue, header2); + Assert.Equal(headersResultPart2.GetCell(2).StringCellValue, header3); + + var firstRowPart2 = sheetPart2.GetRow(1); + Assert.Equal(firstRowPart2.GetCell(0).NumericCellValue, 1048573); + } + finally + { + File.Delete(fileName); + File.Delete($"{Path.GetFileNameWithoutExtension(fileName)}_part_2.xlsx"); + } + } + } +} \ No newline at end of file From ad4209a604af98de63b9c19f0e5482b52d33089a Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Fri, 2 Feb 2024 13:11:47 +0300 Subject: [PATCH 05/12] move npoi realization to separate project --- Curiosity.Utils.sln | 7 + ...uriosity.FileDataReaderWriters.Npoi.csproj | 16 ++ .../NpoiXlsFileWriter.cs | 13 +- .../NpoiXlsMultiFileWriter.cs | 14 +- .../Curiosity.FileDataReaderWriters.csproj | 8 +- .../Helpers/Guard.cs | 151 +++++++++--------- .../Readers/CsvFileDataReader.cs | 3 + .../Readers/IFileDataReader.cs | 5 +- .../Readers/XlsFileExtensions.cs | 1 + .../Readers/XlsxFileDataReader.cs | 3 + .../Style/FontStyle.cs | 4 +- .../Writers/CsvFileWriter.cs | 3 + .../Writers/FlexCelXlsFileWriter.cs | 2 + .../Writers/FlexCelXlsMultiFileWriter.cs | 3 + .../Writers/IFileWriter.cs | 2 + 15 files changed, 137 insertions(+), 98 deletions(-) create mode 100644 src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj rename src/FileData/{Curiosity.FileDataReaderWriters/Writers => Curiosity.FileDataReaderWriters.Npoi}/NpoiXlsFileWriter.cs (95%) rename src/FileData/{Curiosity.FileDataReaderWriters/Writers => Curiosity.FileDataReaderWriters.Npoi}/NpoiXlsMultiFileWriter.cs (96%) diff --git a/Curiosity.Utils.sln b/Curiosity.Utils.sln index 897bd7a..892dee4 100644 --- a/Curiosity.Utils.sln +++ b/Curiosity.Utils.sln @@ -159,6 +159,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileData", "FileData", "{97 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.UnitTests", "tests\UnitTests\Curiosity.FileDataReaderWriters.UnitTests\Curiosity.FileDataReaderWriters.UnitTests.csproj", "{14444441-9159-44B1-AEE0-50B9C8F6E90C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.Npoi", "src\FileData\Curiosity.FileDataReaderWriters.Npoi\Curiosity.FileDataReaderWriters.Npoi.csproj", "{7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -357,6 +359,10 @@ Global {14444441-9159-44B1-AEE0-50B9C8F6E90C}.Debug|Any CPU.Build.0 = Debug|Any CPU {14444441-9159-44B1-AEE0-50B9C8F6E90C}.Release|Any CPU.ActiveCfg = Release|Any CPU {14444441-9159-44B1-AEE0-50B9C8F6E90C}.Release|Any CPU.Build.0 = Release|Any CPU + {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -434,6 +440,7 @@ Global {D135ADFA-0A52-41C0-876F-691876A780E1} = {2B8CCF93-24F0-45F9-9961-85695351141E} {973E81A0-574E-406A-AB95-01B1243A984C} = {55CC9AE1-6978-4ECB-9A0A-0DCE1B66D492} {14444441-9159-44B1-AEE0-50B9C8F6E90C} = {973E81A0-574E-406A-AB95-01B1243A984C} + {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864} = {2B8CCF93-24F0-45F9-9961-85695351141E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BA1A20A2-0D4E-492D-877C-0A36F18FBFF1} diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj new file mode 100644 index 0000000..bdecb91 --- /dev/null +++ b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.1 + latest + + + + + + + + + + + diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/NpoiXlsFileWriter.cs similarity index 95% rename from src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters.Npoi/NpoiXlsFileWriter.cs index aad7d83..5eabfa1 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/NpoiXlsFileWriter.cs @@ -1,10 +1,14 @@ -using Curiosity.FileDataReaderWriters.Style; +using System; +using System.Collections.Generic; +using System.IO; +using Curiosity.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Writers; using ICSharpCode.SharpZipLib.Zip; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; using NPOI.XSSF.Streaming; -namespace Curiosity.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Npoi; /// /// Класс для записи данных в xlsx / xls формате для NPOI @@ -33,7 +37,6 @@ public NpoiXlsFileWriter(string outputFilePath, ILogger logger, int rowAccessWin _outputFilePath = outputFilePath; _logger = logger; _workbook = new SXSSFWorkbook(rowAccessWindowSize); - _workbook.UseZip64 = UseZip64.On; _sheet = _workbook.CreateSheet(); //настройка формата даты для ячеек @@ -150,10 +153,6 @@ public void Append(object? value, int? format = null) case string val: cell.SetCellValue(val); break; - case DateOnly val: - cell.SetCellValue(val); - cell.CellStyle = _dataStyle; - break; case DateTime val: cell.SetCellValue(val); cell.CellStyle = _dataStyle; diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/NpoiXlsMultiFileWriter.cs similarity index 96% rename from src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters.Npoi/NpoiXlsMultiFileWriter.cs index 64de85b..73a92e5 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/NpoiXlsMultiFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/NpoiXlsMultiFileWriter.cs @@ -1,11 +1,14 @@ -using Curiosity.FileDataReaderWriters.Helpers; +using System; +using System.Collections.Generic; +using System.IO; +using Curiosity.FileDataReaderWriters.Helpers; using Curiosity.FileDataReaderWriters.Style; -using ICSharpCode.SharpZipLib.Zip; +using Curiosity.FileDataReaderWriters.Writers; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; using NPOI.XSSF.Streaming; -namespace Curiosity.FileDataReaderWriters.Writers; +namespace Curiosity.FileDataReaderWriters.Npoi; /// /// Класс для записи данных в xlsx / xls формате для NPOI с разбитием на несколько файлов @@ -46,7 +49,6 @@ public NpoiXlsMultiFileWriter(string savePath, string fileName, ILogger logger, _logger = logger; _fileName = fileName; _workbook = new SXSSFWorkbook(rowAccessWindowSize); - _workbook.UseZip64 = UseZip64.On; _sheet = _workbook.CreateSheet(); //настройка формата даты для ячеек @@ -162,10 +164,6 @@ public void Append(object? value, int? format = null) case string val: cell.SetCellValue(val); break; - case DateOnly val: - cell.SetCellValue(val); - cell.CellStyle = _dataStyle; - break; case DateTime val: cell.SetCellValue(val); cell.CellStyle = _dataStyle; diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj index 780b34c..7adb6a4 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj @@ -1,15 +1,15 @@ - net6.0 + netstandard2.1 enable enable + latest - @@ -18,10 +18,6 @@ - - - - $(NoWarn);1591 diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs index 8721218..3502b2c 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs @@ -1,84 +1,85 @@ using System.Runtime.CompilerServices; +using global::System; namespace Curiosity.FileDataReaderWriters; -public static partial class Guard +internal static class Guard +{ + /// + /// Проверяет, что параметр не null. + /// + /// Значение параметра. + /// Название параметра. + /// Тип параметра. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotNull(T? parameter, string parameterName) where T : class { - /// - /// Проверяет, что параметр не null. - /// - /// Значение параметра. - /// Название параметра. - /// Тип параметра. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AssertNotNull(T? parameter, string parameterName) where T: class - { - if (parameter == null) - throw new ArgumentNullException(parameterName); - } - - /// - /// Проверяет, что параметр не null. - /// - /// Значение параметра. - /// Название параметра. - /// Тип параметра. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AssertHasValue(Nullable parameter, string parameterName) where T: struct - { - if (!parameter.HasValue) - throw new ArgumentNullException(parameterName); - } + if (parameter == null) + throw new ArgumentNullException(parameterName); + } - /// - /// Проверяет, что строка не пустая. - /// - /// Значение параметра - /// Название параметра - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AssertNotEmpty(string? parameter, string parameterName) - { - if (String.IsNullOrWhiteSpace(parameter)) - throw new ArgumentNullException(parameterName); - } + /// + /// Проверяет, что параметр не null. + /// + /// Значение параметра. + /// Название параметра. + /// Тип параметра. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertHasValue(Nullable parameter, string parameterName) where T : struct + { + if (!parameter.HasValue) + throw new ArgumentNullException(parameterName); + } + + /// + /// Проверяет, что строка не пустая. + /// + /// Значение параметра + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotEmpty(string? parameter, string parameterName) + { + if (String.IsNullOrWhiteSpace(parameter)) + throw new ArgumentNullException(parameterName); + } - /// - /// Проверяет, что значение находится в заданном диапазоне. - /// - /// Значение параметра - /// Минимальное допустимое значение - /// Максимальное допустимое значение - /// Название параметра - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AssertInRange(int parameter, int minValue, int maxValue, string parameterName) - { - if (parameter < minValue || parameter > maxValue) - throw new ArgumentOutOfRangeException(parameterName); - } + /// + /// Проверяет, что значение находится в заданном диапазоне. + /// + /// Значение параметра + /// Минимальное допустимое значение + /// Максимальное допустимое значение + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertInRange(int parameter, int minValue, int maxValue, string parameterName) + { + if (parameter < minValue || parameter > maxValue) + throw new ArgumentOutOfRangeException(parameterName); + } - /// - /// Проверяет, что значение не отрицательно. - /// - /// Значение параметра - /// Название параметра - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AssertNotNegative(int? parameter, string parameterName) - { - if (!parameter.HasValue) return; - AssertNotNegative(parameter.Value, parameterName); - } + /// + /// Проверяет, что значение не отрицательно. + /// + /// Значение параметра + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotNegative(int? parameter, string parameterName) + { + if (!parameter.HasValue) return; + AssertNotNegative(parameter.Value, parameterName); + } - /// - /// Проверяет, что значение не отрицательно. - /// - /// Значение параметра - /// Название параметра - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AssertNotNegative(int parameter, string parameterName) - { - if (parameter < 0) - throw new ArgumentOutOfRangeException(parameterName); - } - } \ No newline at end of file + /// + /// Проверяет, что значение не отрицательно. + /// + /// Значение параметра + /// Название параметра + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AssertNotNegative(int parameter, string parameterName) + { + if (parameter < 0) + throw new ArgumentOutOfRangeException(parameterName); + } +} \ No newline at end of file diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs index 5141d9c..7c88cc7 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs @@ -1,4 +1,7 @@ using System.Text; +using global::System; +using global::System.Collections.Generic; +using global::System.IO; using Sylvan.Data.Csv; namespace Curiosity.FileDataReaderWriters.Readers; diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Readers/IFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/IFileDataReader.cs index 32be21a..4fe505d 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Readers/IFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/IFileDataReader.cs @@ -1,4 +1,7 @@ -namespace Curiosity.FileDataReaderWriters.Readers; +using global::System; +using global::System.Collections.Generic; + +namespace Curiosity.FileDataReaderWriters.Readers; /// /// Общий интерфейс для классов, которые читает загруженные файлы построчно. diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs index a0b4ca0..b25c99c 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs @@ -1,4 +1,5 @@ using FlexCel.XlsAdapter; +using global::System; namespace Curiosity.FileDataReaderWriters.Readers { diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs index 0cd107f..4e7a3ff 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs @@ -2,6 +2,9 @@ using Curiosity.FileDataReaderWriters.Resources; using FlexCel.Core; using FlexCel.XlsAdapter; +using global::System; +using global::System.Collections.Generic; +using global::System.IO; namespace Curiosity.FileDataReaderWriters.Readers; diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Style/FontStyle.cs b/src/FileData/Curiosity.FileDataReaderWriters/Style/FontStyle.cs index 0ae36a4..fdcae65 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Style/FontStyle.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Style/FontStyle.cs @@ -1,4 +1,6 @@ -namespace Curiosity.FileDataReaderWriters.Style; +using global::System; + +namespace Curiosity.FileDataReaderWriters.Style; [Flags] public enum FontStyle diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs index 799e76c..a04dccb 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs @@ -4,6 +4,9 @@ using CsvHelper.Configuration; using Curiosity.FileDataReaderWriters.Style; using Curiosity.FileDataReaderWriters.Writers; +using global::System; +using global::System.Collections.Generic; +using global::System.IO; namespace Curiosity.FileDataReaderWriters; diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs index eaa6c62..9f196cc 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs @@ -2,6 +2,8 @@ using Curiosity.FileDataReaderWriters.Style; using FlexCel.Core; using FlexCel.XlsAdapter; +using global::System; +using global::System.Collections.Generic; namespace Curiosity.FileDataReaderWriters.Writers; diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs index 7d741a5..a096393 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs @@ -3,6 +3,9 @@ using Curiosity.FileDataReaderWriters.Writers; using FlexCel.Core; using FlexCel.XlsAdapter; +using global::System; +using global::System.Collections.Generic; +using global::System.IO; using Microsoft.Extensions.Logging; namespace Curiosity.FileDataReaderWriters diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/IFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/IFileWriter.cs index a1ba801..559e556 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/IFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Writers/IFileWriter.cs @@ -1,4 +1,6 @@ using Curiosity.FileDataReaderWriters.Style; +using global::System; +using global::System.Collections.Generic; namespace Curiosity.FileDataReaderWriters.Writers; From 7c397e98b639e9c1334001dafdf97dc74ff8816b Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Fri, 2 Feb 2024 13:26:50 +0300 Subject: [PATCH 06/12] move sylvan to separate project --- Curiosity.Utils.sln | 7 + .../CsvFileDataReader.cs | 11 +- .../CsvFileWriter.cs | 8 +- ...iosity.FileDataReaderWriters.Sylvan.csproj | 14 ++ .../Curiosity.FileDataReaderWriters.csproj | 2 - .../Helpers/Guard.cs | 3 +- .../Readers/XlsFileExtensions.cs | 19 -- .../Readers/XlsxFileDataReader.cs | 211 ------------------ .../Writers/FlexCelXlsFileWriter.cs | 125 ----------- .../Writers/FlexCelXlsMultiFileWriter.cs | 176 --------------- .../Writers/XlsFileExtensions.cs | 20 -- 11 files changed, 32 insertions(+), 564 deletions(-) rename src/FileData/{Curiosity.FileDataReaderWriters/Readers => Curiosity.FileDataReaderWriters.Sylvan}/CsvFileDataReader.cs (97%) rename src/FileData/{Curiosity.FileDataReaderWriters/Writers => Curiosity.FileDataReaderWriters.Sylvan}/CsvFileWriter.cs (93%) create mode 100644 src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj delete mode 100644 src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs delete mode 100644 src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs delete mode 100644 src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs delete mode 100644 src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs delete mode 100644 src/FileData/Curiosity.FileDataReaderWriters/Writers/XlsFileExtensions.cs diff --git a/Curiosity.Utils.sln b/Curiosity.Utils.sln index 892dee4..1c5d2c0 100644 --- a/Curiosity.Utils.sln +++ b/Curiosity.Utils.sln @@ -161,6 +161,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWri EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.Npoi", "src\FileData\Curiosity.FileDataReaderWriters.Npoi\Curiosity.FileDataReaderWriters.Npoi.csproj", "{7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.Sylvan", "src\FileData\Curiosity.FileDataReaderWriters.Sylvan\Curiosity.FileDataReaderWriters.Sylvan.csproj", "{BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -363,6 +365,10 @@ Global {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}.Debug|Any CPU.Build.0 = Debug|Any CPU {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}.Release|Any CPU.ActiveCfg = Release|Any CPU {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}.Release|Any CPU.Build.0 = Release|Any CPU + {BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -441,6 +447,7 @@ Global {973E81A0-574E-406A-AB95-01B1243A984C} = {55CC9AE1-6978-4ECB-9A0A-0DCE1B66D492} {14444441-9159-44B1-AEE0-50B9C8F6E90C} = {973E81A0-574E-406A-AB95-01B1243A984C} {7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864} = {2B8CCF93-24F0-45F9-9961-85695351141E} + {BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942} = {2B8CCF93-24F0-45F9-9961-85695351141E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BA1A20A2-0D4E-492D-877C-0A36F18FBFF1} diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileDataReader.cs similarity index 97% rename from src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs rename to src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileDataReader.cs index 7c88cc7..4d3a5d7 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Readers/CsvFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileDataReader.cs @@ -1,10 +1,11 @@ -using System.Text; -using global::System; -using global::System.Collections.Generic; -using global::System.IO; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Curiosity.FileDataReaderWriters.Readers; using Sylvan.Data.Csv; -namespace Curiosity.FileDataReaderWriters.Readers; +namespace Curiosity.FileDataReaderWriters.Sylvan; /// /// Класс для построчного чтения CSV файлов. diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileWriter.cs similarity index 93% rename from src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileWriter.cs index a04dccb..8bca9e1 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/CsvFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileWriter.cs @@ -1,14 +1,14 @@ +using System; +using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Text; using CsvHelper; using CsvHelper.Configuration; using Curiosity.FileDataReaderWriters.Style; using Curiosity.FileDataReaderWriters.Writers; -using global::System; -using global::System.Collections.Generic; -using global::System.IO; -namespace Curiosity.FileDataReaderWriters; +namespace Curiosity.FileDataReaderWriters.Sylvan; /// /// Запись данных в .csv формате diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj new file mode 100644 index 0000000..2c92372 --- /dev/null +++ b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.1 + enable + latest + + + + + + + + diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj index 7adb6a4..71fef79 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj @@ -10,8 +10,6 @@ - - diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs index 3502b2c..0722901 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters/Helpers/Guard.cs @@ -1,9 +1,8 @@ using System.Runtime.CompilerServices; -using global::System; namespace Curiosity.FileDataReaderWriters; -internal static class Guard +public static class Guard { /// /// Проверяет, что параметр не null. diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs deleted file mode 100644 index b25c99c..0000000 --- a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsFileExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using FlexCel.XlsAdapter; -using global::System; - -namespace Curiosity.FileDataReaderWriters.Readers -{ - /// - /// Методы расширения для в TMS FlexCell - /// - internal static class XlsFileExtensions - { - /// - /// Возвращает обрезанную строку из указанной ячейки или пустую строку, если в ячейке ничего нет - /// - public static string GetTrimmedStringFromCell(this XlsFile xls, int rIdx, int cIdx) - { - return (xls.GetStringFromCell(rIdx, cIdx) ?? String.Empty).Trim(); - } - } -} diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs deleted file mode 100644 index 4e7a3ff..0000000 --- a/src/FileData/Curiosity.FileDataReaderWriters/Readers/XlsxFileDataReader.cs +++ /dev/null @@ -1,211 +0,0 @@ -using Curiosity.FileDataReaderWriters.Helpers; -using Curiosity.FileDataReaderWriters.Resources; -using FlexCel.Core; -using FlexCel.XlsAdapter; -using global::System; -using global::System.Collections.Generic; -using global::System.IO; - -namespace Curiosity.FileDataReaderWriters.Readers; - -/// -/// Класс для построчного чтения данных их Xlsx/xlsx файлов. -/// -/// -public class XlsxFileDataReader : IFileDataReader -{ - /// - /// Максимальное количество пустых строк подряд, после которых мы перестаем читать файл. - /// - private const int MaxSequentialEmptyRowsCount = 10; - - private readonly Stream _fileStream; - private readonly bool _disposeFileStream; - - private XlsFile? _xls; - private readonly int? _columnsCount; - private readonly int _maxColumnsCount; - - private int _rIdx; - private int _sequentialEmptyRowsCount; - - private IReadOnlyList? _currentRow; - private readonly List _buffer; - - /// - public int MaxSupportedRowsCount => ExcelConstants.XlsxRowsMax; - - /// - /// - /// Уменьшаем на 1, потому что после чтения мы всегда увеличиваем после чтения очередной строки. - /// - public int CurrentRowIdx => _rIdx - 1; - - private XlsxFileDataReader( - Stream fileStream, - bool disposeFileStream, - XlsFile xls, - int? columnsCount, - int maxColumnsCount, - int startRowIdx) - { - Guard.AssertNotNull(fileStream, nameof(fileStream)); - Guard.AssertNotNull(xls, nameof(xls)); - - _fileStream = fileStream; - _disposeFileStream = disposeFileStream; - - _xls = xls; - _columnsCount = columnsCount; - _maxColumnsCount = maxColumnsCount; - - _buffer = columnsCount.HasValue - ? new List(columnsCount.Value) - : new List(); - - _rIdx = Math.Max(1, startRowIdx); - _sequentialEmptyRowsCount = 0; - } - - /// - /// Создает готовый к работе . - /// - /// Поток с данными файла. - /// Количество колонок в Excel файле. Если не указано, то количество колонок в каждой строке будет определяться автоматически. - /// Номер строки, начиная с которой надо читать файл. - /// Нужно ли освобождать после завершения чтения. - public static XlsxFileDataReader CreateReader( - string fileName, - Stream fileStream, - int? columnsCount = null, - int startRowIdx = 1, - bool disposeFileStream = false) - { - Guard.AssertNotNull(fileStream, nameof(fileStream)); - Guard.AssertNotEmpty(fileName, nameof(fileName)); - Guard.AssertNotNegative(columnsCount, nameof(columnsCount)); - Guard.AssertNotNegative(startRowIdx, nameof(startRowIdx)); - - var xls = new XlsFile(); - - TFileFormats fileFormat; - int maxColumnsCount; - var fileExtension = Path.GetExtension(fileName).ToLower(); - switch (fileExtension) - { - case ".xls": - fileFormat = TFileFormats.Xls; - maxColumnsCount = ExcelConstants.XlsColMax; - break; - case ".xlsx": - fileFormat = TFileFormats.Xlsx; - maxColumnsCount = ExcelConstants.XlsxColMax; - break; - default: - throw new ArgumentOutOfRangeException(nameof(fileName), fileName, - LNG.Get("Файл с расширением \"{0}\" не является Excel (.xls/.xlsx)", fileExtension)); - } - - ColumnImportType[]? columnFormats = null; - if (columnsCount != null) - { - columnFormats = new ColumnImportType[columnsCount.Value]; - for (var i = 0; i < columnsCount; i++) - { - columnFormats[i] = ColumnImportType.Text; - } - } - - // для xlsx пофиг на разделитель, просто сигнатура метода кривая, - // надо хоть что-то указать - var fieldDelimiter = ','; - xls.Open(fileStream, fileFormat, fieldDelimiter, 1, 1, columnFormats); - - // выбираем первый лист - if (xls.SheetCount < 1) - throw new ArgumentException(LNG.Get("Файл должен содержать хотя бы один лист")); - - xls.ActiveSheet = 1; - - return new XlsxFileDataReader( - fileStream, - disposeFileStream, - xls, - columnsCount, - maxColumnsCount, - startRowIdx); - } - - /// - public bool Read() - { - while (true) - { - if (_rIdx > MaxSupportedRowsCount) return false; - if (_sequentialEmptyRowsCount > MaxSequentialEmptyRowsCount) return false; - - _buffer.Clear(); - var isEmptyRow = true; - - // используется, если мы не знаем количество колонок на момент чтения файла - var emptyCells = 0; - const int maxSequenceEmptyCellsCount = 10; - - // условия выхода из цикла ниже в первых строках - for (var cIdx = 1; ; cIdx++) - { - // если знаем количество колонок и вышли за границы, то выходим - if (_columnsCount.HasValue && cIdx > _columnsCount.Value) break; - // если не знаем количество колонок и много пустых ячеек подряд, то выходим - if (!_columnsCount.HasValue && emptyCells >= maxSequenceEmptyCellsCount) break; - // если вышли за граница файла, то тоже выходим - if (cIdx >= _maxColumnsCount) break; - - var cellValue = _xls!.GetTrimmedStringFromCell(_rIdx, cIdx); - if (cellValue.Length == 0) - { - emptyCells++; - _buffer.Add(null); - } - else - { - isEmptyRow = false; - emptyCells = 0; - _buffer.Add(cellValue); - } - } - - _rIdx++; - - if (isEmptyRow) - { - _sequentialEmptyRowsCount++; - _currentRow = null; - - // если прочитали пустую строку, попробуем прочитать еще одну строку, - // чтобы упростить клиентский код - continue; - } - - // если какие-то данные были, сбросим счетчик пустых строк - _sequentialEmptyRowsCount = 0; - - // сохраним данные, чтобы вернуть по требованию - _currentRow = _buffer; - - return true; - } - } - - /// - public IReadOnlyList? GetRow() => _currentRow; - - /// - public void Dispose() - { - _xls = null!; - - if (_disposeFileStream) - _fileStream.Dispose(); - } -} diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs deleted file mode 100644 index 9f196cc..0000000 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsFileWriter.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System.Text; -using Curiosity.FileDataReaderWriters.Style; -using FlexCel.Core; -using FlexCel.XlsAdapter; -using global::System; -using global::System.Collections.Generic; - -namespace Curiosity.FileDataReaderWriters.Writers; - -/// -/// Запись данных в xlsx / xls формате -/// -public class FlexCelXlsFileWriter : IFileWriter -{ - private readonly XlsFile _xls; - - private IReadOnlyList? _headers; - - private readonly string _outputFilePath; - private readonly TFileFormats _fileFormat; - private readonly bool _isNeedToFitHeader; - - private int _currentRow = 1; - private int _currentCell = 1; - private readonly int _defaultHeaderXf; - private readonly int _defaultDataXf; - - /// Полное имя файла - /// если true, то заголовки растягиваются по ширине текста - public FlexCelXlsFileWriter( - string outputFilePath, - TFileFormats fileFormat, - bool isNeedToFitHeader) - { - _outputFilePath = outputFilePath; - _fileFormat = fileFormat; - _isNeedToFitHeader = isNeedToFitHeader; - - _xls = new XlsFile(1, true); - (_defaultHeaderXf, _defaultDataXf) = _xls.AddDefaultFormats(); - } - - public int AddFormat(FormatSettings formatSettings) - { - var fmt = _xls.GetDefaultFormat; - fmt.Format = formatSettings.DataFormat; - fmt.Font.Size20 = formatSettings.FontSize * 20; - fmt.WrapText = formatSettings.WrapText; - - fmt.HAlignment = formatSettings.TextAlignment switch - { - TextAlignment.Left => THFlxAlignment.left, - TextAlignment.Center => THFlxAlignment.center, - TextAlignment.Right => THFlxAlignment.right, - TextAlignment.Justify => THFlxAlignment.justify, - _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.TextAlignment)) - }; - - fmt.Font.Style = formatSettings.FontStyle switch - { - FontStyle.None => TFlxFontStyles.None, - FontStyle.Bold => TFlxFontStyles.Bold, - FontStyle.Italic => TFlxFontStyles.Italic, - _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.FontStyle)) - }; - - return _xls.AddFormat(fmt); - } - - public int AddDefaultFormat() - { - return _xls.AddFormat(_xls.GetDefaultFormat); - } - - public void AddHeaders(IReadOnlyList data) - { - _headers = data ?? throw new ArgumentNullException(nameof(data)); - - for (var i = 0; i < data.Count; i++) - { - var datum = data[i]; - Append(datum.Value, datum.Format ?? _defaultHeaderXf); - } - - EndLine(); - } - - public void AppendLine(IReadOnlyList data) - { - if (data == null) throw new ArgumentNullException(nameof(data)); - - for (var i = 0; i < data.Count; i++) - { - var datum = data[i]; - Append(datum.Value, datum.Format); - } - - EndLine(); - } - - public void Append(object? value, int? format = null) - { - _xls.SetCellValue(_currentRow, _currentCell++, value, format ?? _defaultDataXf); - } - - public void EndLine() - { - _currentRow++; - _currentCell = 1; - } - - public void Flush() - { - // подгоним ширину, если надо - if (_isNeedToFitHeader && _headers?.Count > 0) - _xls.AutofitCol(1, _headers.Count, false, 1.1f); - - _xls.Save(_outputFilePath, _fileFormat, ';', Encoding.UTF8); - } - - public void Dispose() - { - // тут нечего освобождать - } -} diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs deleted file mode 100644 index a096393..0000000 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/FlexCelXlsMultiFileWriter.cs +++ /dev/null @@ -1,176 +0,0 @@ -using Curiosity.FileDataReaderWriters.Helpers; -using Curiosity.FileDataReaderWriters.Style; -using Curiosity.FileDataReaderWriters.Writers; -using FlexCel.Core; -using FlexCel.XlsAdapter; -using global::System; -using global::System.Collections.Generic; -using global::System.IO; -using Microsoft.Extensions.Logging; - -namespace Curiosity.FileDataReaderWriters -{ - /// - /// Класс для записи звонков в xlsx. Основная фишка - если количество строк больше лимита, то создаются отдельные файлы автоматчиески - /// - public class FlexCelXlsMultiFileWriter : IFileWriter - { - private readonly XlsFile _xls; - private readonly ILogger _logger; - - private IReadOnlyList? _headers; - - private readonly string _savePath; - private readonly string _fileName; - private readonly TFileFormats _fileFormat; - private readonly bool _isNeedToFitHeader; - - private int _currentRow = 1; - private int _currentCell = 1; - private int _partNumber = 1; - private readonly int _defaultHeaderXf; - private readonly int _defaultDataXf; - - /// Имя файла с расширением - /// если true, то заголовки растягиватся по ширине текста - public FlexCelXlsMultiFileWriter( - string savePath, - string fileName, - TFileFormats fileFormat, - bool isNeedToFitHeader, - ILogger logger) - { - if (String.IsNullOrWhiteSpace(savePath)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(savePath)); - if (String.IsNullOrWhiteSpace(fileName)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(fileName)); - - _savePath = savePath; - _fileName = fileName; - _fileFormat = fileFormat; - _isNeedToFitHeader = isNeedToFitHeader; - - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - - _xls = new XlsFile(1, true); - (_defaultHeaderXf, _defaultDataXf) = _xls.AddDefaultFormats(); - } - - public int AddFormat(FormatSettings formatSettings) - { - var fmt = _xls.GetDefaultFormat; - fmt.Format = formatSettings.DataFormat; - fmt.Font.Size20 = formatSettings.FontSize * 20; - fmt.WrapText = formatSettings.WrapText; - - fmt.HAlignment = formatSettings.TextAlignment switch - { - TextAlignment.Left => THFlxAlignment.left, - TextAlignment.Center => THFlxAlignment.center, - TextAlignment.Right => THFlxAlignment.right, - TextAlignment.Justify => THFlxAlignment.justify, - _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.TextAlignment)) - }; - - fmt.Font.Style = formatSettings.FontStyle switch - { - FontStyle.None => TFlxFontStyles.None, - FontStyle.Bold => TFlxFontStyles.Bold, - FontStyle.Italic => TFlxFontStyles.Italic, - _ => throw new ArgumentOutOfRangeException(nameof(formatSettings.FontStyle)) - }; - - return _xls.AddFormat(fmt); - } - - public int AddDefaultFormat() - { - return _xls.AddFormat(_xls.GetDefaultFormat); - } - - public void AddHeaders(IReadOnlyList data) - { - _headers = data ?? throw new ArgumentNullException(nameof(data)); - - for (var i = 0; i < _headers.Count; i++) - { - var header = _headers[i]; - _xls.SetCellValue(_currentRow, _currentCell++, header.Value, header.Format ?? _defaultHeaderXf); - } - - EndLine(); - } - - public void AppendLine(IReadOnlyList data) - { - if (data == null) throw new ArgumentNullException(nameof(data)); - - for (var i = 0; i < data.Count; i++) - { - var datum = data[i]; - Append(datum.Value, datum.Format); - } - - EndLine(); - } - - public void Append(object? value, int? format = null) - { - // если новый файл - запишем заголовок - if (_currentRow == 1 && _headers?.Count > 0) - { - for (var i = 0; i < _headers.Count; i++) - { - var header = _headers[i]; - _xls.SetCellValue(_currentRow, _currentCell++, header.Value, header.Format ?? _defaultHeaderXf); - } - - EndLine(); - } - - _xls.SetCellValue(_currentRow, _currentCell++, value, format ?? _defaultDataXf); - } - - public void EndLine() - { - _currentRow++; - _currentCell = 1; - - // если лимит - сбросим данные в файл - if (_currentRow >= ExcelConstants.XlsxRowsMax) - Flush(); - } - - public void Flush() - { - // если ни чего нет - выходим - if (_currentRow == 1) - return; - - // подгоним ширину - if (_isNeedToFitHeader && _headers?.Count > 0) - _xls.AutofitCol(1, _headers.Count, false, 1.1f); - - // сгенерим имя - var fileName = _fileName; - if (_partNumber > 1) - { - fileName = $"{Path.GetFileNameWithoutExtension(_fileName)}_part_{_partNumber}{Path.GetExtension(_fileName)}"; - } - var outputFilePath = Path.Combine(_savePath, fileName); - - // сохраним - _logger.LogDebug($"Сохраняем файл \"{outputFilePath}\"..."); - _xls.Save(outputFilePath, _fileFormat); - _logger.LogInformation($"Файл \"{outputFilePath}\" успешно сохранён"); - - // обнулим состояние - _xls.ClearSheet(); - _partNumber++; - _currentRow = 1; - } - - public void Dispose() - { - // нечего освобождать - } - } -} \ No newline at end of file diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Writers/XlsFileExtensions.cs b/src/FileData/Curiosity.FileDataReaderWriters/Writers/XlsFileExtensions.cs deleted file mode 100644 index e4d5d3a..0000000 --- a/src/FileData/Curiosity.FileDataReaderWriters/Writers/XlsFileExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using FlexCel.Core; -using FlexCel.XlsAdapter; - -namespace Curiosity.FileDataReaderWriters.Writers; - -public static class XlsFileExtensions -{ - public static (int HeaderXf, int DataXf) AddDefaultFormats(this XlsFile xls) - { - var fmt = xls.GetDefaultFormat; - fmt.Font.Style = TFlxFontStyles.Bold; - fmt.WrapText = false; - var headerXf = xls.AddFormat(fmt); - - fmt = xls.GetDefaultFormat; - var dataXf = xls.AddFormat(fmt); - - return (headerXf, dataXf); - } -} \ No newline at end of file From 9e1c5f89a624ecfdfd2c4cc1747a9ef8fa24cf4c Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Fri, 2 Feb 2024 14:12:51 +0300 Subject: [PATCH 07/12] add package descriptions --- .../CHANGELOG.md | 5 +++ ...uriosity.FileDataReaderWriters.Npoi.csproj | 40 ++++++++++++++++++- .../CHANGELOG.md | 5 +++ ...iosity.FileDataReaderWriters.Sylvan.csproj | 38 +++++++++++++++++- .../CHANGELOG.md | 5 +++ .../Curiosity.FileDataReaderWriters.csproj | 40 ++++++++++++++++++- ...ity.FileDataReaderWriters.UnitTests.csproj | 1 + .../NpoiXlsFileWriter_Should.cs | 3 +- .../NpoiXlsMultiFileWriter_Should.cs | 3 +- 9 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 src/FileData/Curiosity.FileDataReaderWriters.Npoi/CHANGELOG.md create mode 100644 src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CHANGELOG.md create mode 100644 src/FileData/Curiosity.FileDataReaderWriters/CHANGELOG.md diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Npoi/CHANGELOG.md b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/CHANGELOG.md new file mode 100644 index 0000000..46b34f7 --- /dev/null +++ b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## [1.0.0] - 2024-02-02 + +Package was released. diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj index bdecb91..75af1c5 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj @@ -2,9 +2,43 @@ netstandard2.1 - latest + + Curiosity.FileDataReaderWriters.Npoi + Curiosity.FileDataReaderWriters.Npoi + Npoi realization for working with xls/xlsx/csv files + Single and multifile writing to xlsx file. Uses streaming version of workbook to reduce peak memory consumption. + Curiosity; FileDataReaderWriters; Npoi; siisltd + English + + 1.0.0 + 1.0.0 + 1.0.0 + + Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Timur Sidoriuk (@shockthunder) + SIIS Ltd + SIIS Ltd, 2024 + + false + MIT + + https://github.com/siisltd/Curiosity.Utils + git + https://github.com/siisltd/Curiosity.Utils + https://github.com/siisltd/Curiosity.Utils/tree/master/src/FileData/Curiosity.FileDataReaderWriters.Npoi/CHANGELOG.md + + 10 + enable + true + + + + siisltd.png + + + + @@ -13,4 +47,8 @@ + + bin\Release\Curiosity.FileDataReaderWriters.Npoi.xml + + diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CHANGELOG.md b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CHANGELOG.md new file mode 100644 index 0000000..46b34f7 --- /dev/null +++ b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## [1.0.0] - 2024-02-02 + +Package was released. diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj index 2c92372..a372598 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj @@ -2,13 +2,49 @@ netstandard2.1 + + Curiosity.FileDataReaderWriters.Sylvan + Curiosity.FileDataReaderWriters.Sylvan + Sylvan realization for working with csv files + Read and write to csv file. Low memory consumption due to bufferization. + Curiosity; FileDataReaderWriters; Sylvan; siisltd + English + + 1.0.0 + 1.0.0 + 1.0.0 + + Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Timur Sidoriuk (@shockthunder) + SIIS Ltd + SIIS Ltd, 2024 + + false + MIT + + https://github.com/siisltd/Curiosity.Utils + git + https://github.com/siisltd/Curiosity.Utils + https://github.com/siisltd/Curiosity.Utils/tree/master/src/FileData/Curiosity.FileDataReaderWriters.Npoi/CHANGELOG.md + + 10 enable - latest + true + + + + siisltd.png + + + + + + bin\Release\Curiosity.FileDataReaderWriters.Sylvan.xml + diff --git a/src/FileData/Curiosity.FileDataReaderWriters/CHANGELOG.md b/src/FileData/Curiosity.FileDataReaderWriters/CHANGELOG.md new file mode 100644 index 0000000..46b34f7 --- /dev/null +++ b/src/FileData/Curiosity.FileDataReaderWriters/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## [1.0.0] - 2024-02-02 + +Package was released. diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj index 71fef79..16b3e57 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj @@ -3,10 +3,44 @@ netstandard2.1 enable + + Curiosity.FileDataReaderWriters + Curiosity.FileDataReaderWriters + Base classes for working with xls/xlsx/csv files + Base format settings, excel constants and reader/writer intefaces. + Curiosity; FileDataReaderWriters; siisltd + English + + 1.0.0 + 1.0.0 + 1.0.0 + + Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Timur Sidoriuk (@shockthunder) + SIIS Ltd + SIIS Ltd, 2024 + + false + MIT + + https://github.com/siisltd/Curiosity.Utils + git + https://github.com/siisltd/Curiosity.Utils + https://github.com/siisltd/Curiosity.Utils/tree/master/src/FileData/Curiosity.FileDataReaderWriters/CHANGELOG.md + + 10 enable - latest + true + + + + + siisltd.png + + + + @@ -21,4 +55,8 @@ $(NoWarn);1591 $(NoWarn);1573 + + + bin\Release\Curiosity.FileDataReaderWriters.xml + diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj index a18fd5f..ce34f46 100644 --- a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/Curiosity.FileDataReaderWriters.UnitTests.csproj @@ -24,6 +24,7 @@ + diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs index b8616e0..486ac9f 100644 --- a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs @@ -1,4 +1,5 @@ -using Curiosity.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Npoi; +using Curiosity.FileDataReaderWriters.Style; using Curiosity.FileDataReaderWriters.Writers; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs index acd84a2..dfeae45 100644 --- a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs @@ -1,4 +1,5 @@ -using Curiosity.FileDataReaderWriters.Style; +using Curiosity.FileDataReaderWriters.Npoi; +using Curiosity.FileDataReaderWriters.Style; using Curiosity.FileDataReaderWriters.Writers; using Microsoft.Extensions.Logging; using NPOI.SS.UserModel; From 7299816e0a8fb9540831df330d6466b13fb62b4a Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Fri, 2 Feb 2024 14:18:24 +0300 Subject: [PATCH 08/12] update authors --- .../Curiosity.FileDataReaderWriters.Npoi.csproj | 2 +- .../Curiosity.FileDataReaderWriters.Sylvan.csproj | 2 +- .../Curiosity.FileDataReaderWriters.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj index 75af1c5..aae13a3 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters.Npoi/Curiosity.FileDataReaderWriters.Npoi.csproj @@ -14,7 +14,7 @@ 1.0.0 1.0.0 - Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Timur Sidoriuk (@shockthunder) + Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Andrey Ioch (@DevCorvette), Timur Sidoriuk (@shockthunder) SIIS Ltd SIIS Ltd, 2024 diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj index a372598..b348fa1 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj @@ -14,7 +14,7 @@ 1.0.0 1.0.0 - Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Timur Sidoriuk (@shockthunder) + Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Andrey Ioch (@DevCorvette), Timur Sidoriuk (@shockthunder) SIIS Ltd SIIS Ltd, 2024 diff --git a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj index 16b3e57..e2258f8 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters/Curiosity.FileDataReaderWriters.csproj @@ -15,7 +15,7 @@ 1.0.0 1.0.0 - Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Timur Sidoriuk (@shockthunder) + Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Andrey Ioch (@DevCorvette), Timur Sidoriuk (@shockthunder) SIIS Ltd SIIS Ltd, 2024 From da147d52533681eeab8b6745e90dace0c72b840f Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Fri, 2 Feb 2024 15:10:20 +0300 Subject: [PATCH 09/12] comment tests --- .../NpoiXlsFileWriter_Should.cs | 2 +- .../NpoiXlsMultiFileWriter_Should.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs index 486ac9f..8c5758c 100644 --- a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsFileWriter_Should.cs @@ -13,7 +13,7 @@ namespace Curiosity.FileDataReaderWriters.UnitTests /// public class NpoiXlsFileWriter_Should { - [Fact] + // [Fact] public void WriteWithHeaders() { //ARRANGE diff --git a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs index dfeae45..857c664 100644 --- a/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs +++ b/tests/UnitTests/Curiosity.FileDataReaderWriters.UnitTests/NpoiXlsMultiFileWriter_Should.cs @@ -13,7 +13,7 @@ namespace Curiosity.FileDataReaderWriters.UnitTests /// public class NpoiXlsMultiFileWriter_Should { - [Fact] + // [Fact] public void WriteWithHeaders() { //ARRANGE From 46b7f33b841c212415e168fd406ea57c5c71643f Mon Sep 17 00:00:00 2001 From: Timur Sidoriuk Date: Fri, 2 Feb 2024 15:14:49 +0300 Subject: [PATCH 10/12] rename sylvan to sylvanCsv --- Curiosity.Utils.sln | 2 +- .../CHANGELOG.md | 0 .../CsvFileDataReader.cs | 2 +- .../CsvFileWriter.cs | 2 +- .../Curiosity.FileDataReaderWriters.SylvanCsv.csproj} | 4 ++-- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/FileData/{Curiosity.FileDataReaderWriters.Sylvan => Curiosity.FileDataReaderWriters.SylvanCsv}/CHANGELOG.md (100%) rename src/FileData/{Curiosity.FileDataReaderWriters.Sylvan => Curiosity.FileDataReaderWriters.SylvanCsv}/CsvFileDataReader.cs (99%) rename src/FileData/{Curiosity.FileDataReaderWriters.Sylvan => Curiosity.FileDataReaderWriters.SylvanCsv}/CsvFileWriter.cs (97%) rename src/FileData/{Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj => Curiosity.FileDataReaderWriters.SylvanCsv/Curiosity.FileDataReaderWriters.SylvanCsv.csproj} (93%) diff --git a/Curiosity.Utils.sln b/Curiosity.Utils.sln index 1c5d2c0..238ff09 100644 --- a/Curiosity.Utils.sln +++ b/Curiosity.Utils.sln @@ -161,7 +161,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWri EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.Npoi", "src\FileData\Curiosity.FileDataReaderWriters.Npoi\Curiosity.FileDataReaderWriters.Npoi.csproj", "{7BDDB1E2-79A6-4E0E-9EE4-C4B03E4D0864}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.Sylvan", "src\FileData\Curiosity.FileDataReaderWriters.Sylvan\Curiosity.FileDataReaderWriters.Sylvan.csproj", "{BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Curiosity.FileDataReaderWriters.SylvanCsv", "src\FileData\Curiosity.FileDataReaderWriters.SylvanCsv\Curiosity.FileDataReaderWriters.SylvanCsv.csproj", "{BEF02973-7CBA-4AB3-9F91-D0F5BFB5E942}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CHANGELOG.md b/src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CHANGELOG.md similarity index 100% rename from src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CHANGELOG.md rename to src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CHANGELOG.md diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileDataReader.cs b/src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CsvFileDataReader.cs similarity index 99% rename from src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileDataReader.cs rename to src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CsvFileDataReader.cs index 4d3a5d7..bb080e3 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileDataReader.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CsvFileDataReader.cs @@ -5,7 +5,7 @@ using Curiosity.FileDataReaderWriters.Readers; using Sylvan.Data.Csv; -namespace Curiosity.FileDataReaderWriters.Sylvan; +namespace Curiosity.FileDataReaderWriters.SylvanCsv; /// /// Класс для построчного чтения CSV файлов. diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileWriter.cs b/src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CsvFileWriter.cs similarity index 97% rename from src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileWriter.cs rename to src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CsvFileWriter.cs index 8bca9e1..dd4e504 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/CsvFileWriter.cs +++ b/src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/CsvFileWriter.cs @@ -8,7 +8,7 @@ using Curiosity.FileDataReaderWriters.Style; using Curiosity.FileDataReaderWriters.Writers; -namespace Curiosity.FileDataReaderWriters.Sylvan; +namespace Curiosity.FileDataReaderWriters.SylvanCsv; /// /// Запись данных в .csv формате diff --git a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj b/src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/Curiosity.FileDataReaderWriters.SylvanCsv.csproj similarity index 93% rename from src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj rename to src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/Curiosity.FileDataReaderWriters.SylvanCsv.csproj index b348fa1..493992f 100644 --- a/src/FileData/Curiosity.FileDataReaderWriters.Sylvan/Curiosity.FileDataReaderWriters.Sylvan.csproj +++ b/src/FileData/Curiosity.FileDataReaderWriters.SylvanCsv/Curiosity.FileDataReaderWriters.SylvanCsv.csproj @@ -3,8 +3,8 @@ netstandard2.1 - Curiosity.FileDataReaderWriters.Sylvan - Curiosity.FileDataReaderWriters.Sylvan + Curiosity.FileDataReaderWriters.SylvanCsv + Curiosity.FileDataReaderWriters.SylvanCsv Sylvan realization for working with csv files Read and write to csv file. Low memory consumption due to bufferization. Curiosity; FileDataReaderWriters; Sylvan; siisltd From 9decd6e338ba186e66022b45f6ef00e71add4525 Mon Sep 17 00:00:00 2001 From: Andrey Ioch Date: Tue, 26 Mar 2024 11:28:04 +0300 Subject: [PATCH 11/12] imprive public id parsing --- src/Misc/Curiosity.Tools/CHANGELOG.md | 7 +++ .../Curiosity.Tools/Curiosity.Tools.csproj | 2 +- src/Misc/Curiosity.Tools/UniqueId/PublicId.cs | 39 +++++++++++-- .../UniqueId/UniqueIdGenerator.cs | 2 + .../UniqueId/PublicIdTests.cs | 56 +++++++++++++++++++ 5 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs diff --git a/src/Misc/Curiosity.Tools/CHANGELOG.md b/src/Misc/Curiosity.Tools/CHANGELOG.md index 8eba5d8..3796e45 100644 --- a/src/Misc/Curiosity.Tools/CHANGELOG.md +++ b/src/Misc/Curiosity.Tools/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.5.2] + +### Changed + +- `PublicId.ToPublicId()` returns 17 chars string instead 16 chars +- `PublicId.TryParse()` can parse hex and dec line + ## [1.5.1] - 2023-11-28 ### Fixed diff --git a/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj b/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj index 8b030c0..a423458 100644 --- a/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj +++ b/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj @@ -12,7 +12,7 @@ 1.0.0 1.0.0 - 1.5.1 + 1.5.2 Max Markelow (@markeli), Andrey Ioch (@DevCorvette) SIIS Ltd diff --git a/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs b/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs index 14f89e2..f2d89ea 100644 --- a/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs +++ b/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs @@ -15,20 +15,51 @@ public static class PublicId /// ID in HEX public static string ToPublicId(this long id) { - return id.ToString("x16", CultureInfo.InvariantCulture); + // number 17 in the format indicates the minimum number of characters in the string + // missing characters are replaced with 0 + // by the first 0, we can detect that the number is hexadecimal, even if all numbers are there + // until 2024 year, our UniqueIdGenerator had generated 16 characters string + return id.ToString("x17", CultureInfo.InvariantCulture); } /// /// Converts an ID from a "public" view to a regular long. /// - /// Public version of the ID (only in hex format) + /// String number can be hex or dec /// Our regular ID /// Successfully parted? public static bool TryParse(string exportId, out long id) { id = 0; - return !String.IsNullOrWhiteSpace(exportId) && - long.TryParse(exportId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out id); + if (String.IsNullOrWhiteSpace(exportId)) + return false; + + // try parse as hex or dec + return IsHexFormat(exportId) + ? long.TryParse(exportId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out id) + : long.TryParse(exportId, out id); + } + + /// + /// Detects that line format is hex or dec + /// + private static bool IsHexFormat(string line) + { + // hex when contains non numeric symbols + for (var i = 0; i < line.Length; i++) + { + if (!char.IsDigit(line[i])) + return true; + } + + // until 2024 year, our UniqueIdGenerator had generated 16 chars string then 17 chars + // always with first 0 + if ((line.Length == 16 || line.Length == 17) && + line[0] == '0') + return true; + + // exactly dec + return false; } } } \ No newline at end of file diff --git a/src/Misc/Curiosity.Tools/UniqueId/UniqueIdGenerator.cs b/src/Misc/Curiosity.Tools/UniqueId/UniqueIdGenerator.cs index 3d8003e..6462bbd 100644 --- a/src/Misc/Curiosity.Tools/UniqueId/UniqueIdGenerator.cs +++ b/src/Misc/Curiosity.Tools/UniqueId/UniqueIdGenerator.cs @@ -24,6 +24,8 @@ public static class UniqueIdGenerator private const int MaxSequenceId = 4096; // 13 apr 2020 (in Ticks / 10000) + // can generate positive long numbers ~70 years from this date, + // then a overflow starts private const long ModelStartEpoch = 63722332800000; private static long _generatorId = -1; diff --git a/tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs b/tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs new file mode 100644 index 0000000..e30b063 --- /dev/null +++ b/tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs @@ -0,0 +1,56 @@ +using FluentAssertions; +using Xunit; + +namespace Curiosity.Tools.UnitTests.UniqueId +{ + public class PublicIdTests + { + // can detect that line is 16 chars hex and parse it to true long value + [Fact] + public void TryParse_Parse16CharsHexLine_LongValue() + { + // arrange + const long value = 10752219502637056; + const string hex = "0026331630007000"; // 16 chars hex + + // act + var canParse = PublicId.TryParse(hex, out var id); + + // assert + canParse.Should().Be(true); + id.Should().Be(value); + } + + // can detect that line is 17 chars hex and parse it to true long value + [Fact] + public void TryParse_Parse17CharsHexLine_LongValue() + { + // arrange + const long value = 10752219502637056; + const string hex = "00026331630007000"; // 17 chars hex + + // act + var canParse = PublicId.TryParse(hex, out var id); + + // assert + canParse.Should().Be(true); + id.Should().Be(value); + } + + // can detect that line is dec and parse it to true long value + [Fact] + public void TryParse_ParseDecLine_LongValue() + { + // arrange + const long value = 10752219502637056; + const string dec = "10752219502637056"; // dec line + + // act + var canParse = PublicId.TryParse(dec, out var id); + + // assert + canParse.Should().Be(true); + id.Should().Be(value); + } + } +} \ No newline at end of file From 730411466e31a4088987f6d15bbd1847f47d9d65 Mon Sep 17 00:00:00 2001 From: Andrey Ioch Date: Fri, 29 Mar 2024 17:11:07 +0300 Subject: [PATCH 12/12] returns 16 chars hex id --- src/Misc/Curiosity.Tools/CHANGELOG.md | 6 ++++++ src/Misc/Curiosity.Tools/Curiosity.Tools.csproj | 2 +- src/Misc/Curiosity.Tools/UniqueId/PublicId.cs | 11 ++++------- .../UniqueId/PublicIdTests.cs | 16 ---------------- 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/Misc/Curiosity.Tools/CHANGELOG.md b/src/Misc/Curiosity.Tools/CHANGELOG.md index 3796e45..03035fb 100644 --- a/src/Misc/Curiosity.Tools/CHANGELOG.md +++ b/src/Misc/Curiosity.Tools/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [1.5.3] + +### Changed + +- `PublicId.ToPublicId()` returns 16 chars string again + ## [1.5.2] ### Changed diff --git a/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj b/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj index a423458..35b85eb 100644 --- a/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj +++ b/src/Misc/Curiosity.Tools/Curiosity.Tools.csproj @@ -12,7 +12,7 @@ 1.0.0 1.0.0 - 1.5.2 + 1.5.3 Max Markelow (@markeli), Andrey Ioch (@DevCorvette) SIIS Ltd diff --git a/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs b/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs index f2d89ea..144f78f 100644 --- a/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs +++ b/src/Misc/Curiosity.Tools/UniqueId/PublicId.cs @@ -15,11 +15,9 @@ public static class PublicId /// ID in HEX public static string ToPublicId(this long id) { - // number 17 in the format indicates the minimum number of characters in the string + // number 16 in the format indicates the minimum number of characters in the string // missing characters are replaced with 0 - // by the first 0, we can detect that the number is hexadecimal, even if all numbers are there - // until 2024 year, our UniqueIdGenerator had generated 16 characters string - return id.ToString("x17", CultureInfo.InvariantCulture); + return id.ToString("x16", CultureInfo.InvariantCulture); } /// @@ -52,9 +50,8 @@ private static bool IsHexFormat(string line) return true; } - // until 2024 year, our UniqueIdGenerator had generated 16 chars string then 17 chars - // always with first 0 - if ((line.Length == 16 || line.Length == 17) && + // our UniqueIdGenerator will generate hex id with first 0 until 2028 year + if ((line.Length == 16) && line[0] == '0') return true; diff --git a/tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs b/tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs index e30b063..697fe58 100644 --- a/tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs +++ b/tests/UnitTests/Misc/Curiosity.Tools.UnitTests/UniqueId/PublicIdTests.cs @@ -21,22 +21,6 @@ public void TryParse_Parse16CharsHexLine_LongValue() id.Should().Be(value); } - // can detect that line is 17 chars hex and parse it to true long value - [Fact] - public void TryParse_Parse17CharsHexLine_LongValue() - { - // arrange - const long value = 10752219502637056; - const string hex = "00026331630007000"; // 17 chars hex - - // act - var canParse = PublicId.TryParse(hex, out var id); - - // assert - canParse.Should().Be(true); - id.Should().Be(value); - } - // can detect that line is dec and parse it to true long value [Fact] public void TryParse_ParseDecLine_LongValue()