Skip to content

Commit

Permalink
Merge pull request #59 from ShockThunder/master
Browse files Browse the repository at this point in the history
Add FileDataReaderWriters project
  • Loading branch information
Markeli authored Feb 2, 2024
2 parents 2183e96 + 46b7f33 commit b3add8f
Show file tree
Hide file tree
Showing 25 changed files with 1,560 additions and 0 deletions.
34 changes: 34 additions & 0 deletions Curiosity.Utils.sln
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@ 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.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
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
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
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -341,6 +353,22 @@ 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
{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
{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
{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
Expand Down Expand Up @@ -414,6 +442,12 @@ 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}
{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}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## [1.0.0] - 2024-02-02

Package was released.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>

<PackageId>Curiosity.FileDataReaderWriters.Npoi</PackageId>
<Title>Curiosity.FileDataReaderWriters.Npoi</Title>
<Description>Npoi realization for working with xls/xlsx/csv files</Description>
<Summary>Single and multifile writing to xlsx file. Uses streaming version of workbook to reduce peak memory consumption.</Summary>
<PackageTags>Curiosity; FileDataReaderWriters; Npoi; siisltd</PackageTags>
<Language>English</Language>

<AssemblyVersion>1.0.0</AssemblyVersion>
<FileVersion>1.0.0</FileVersion>
<PackageVersion>1.0.0</PackageVersion>

<Authors>Max Markelow (@markeli), Andrei Vinogradov (@anri-vin), Andrey Ioch (@DevCorvette), Timur Sidoriuk (@shockthunder)</Authors>
<Company>SIIS Ltd</Company>
<Copyright>SIIS Ltd, 2024</Copyright>

<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>

<PackageProjectUrl>https://github.com/siisltd/Curiosity.Utils</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/siisltd/Curiosity.Utils</RepositoryUrl>
<PackageReleaseNotes>https://github.com/siisltd/Curiosity.Utils/tree/master/src/FileData/Curiosity.FileDataReaderWriters.Npoi/CHANGELOG.md</PackageReleaseNotes>

<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<IsPackable>true</IsPackable>
</PropertyGroup>

<PropertyGroup>
<PackageIcon>siisltd.png</PackageIcon>
</PropertyGroup>

<ItemGroup>
<None Include="..\..\..\siisltd.png" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Curiosity.FileDataReaderWriters\Curiosity.FileDataReaderWriters.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="NPOI" Version="2.6.2" />
</ItemGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\Curiosity.FileDataReaderWriters.Npoi.xml</DocumentationFile>
</PropertyGroup>

</Project>
191 changes: 191 additions & 0 deletions src/FileData/Curiosity.FileDataReaderWriters.Npoi/NpoiXlsFileWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
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.Npoi;

/// <summary>
/// Класс для записи данных в xlsx / xls формате для NPOI
/// </summary>
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<int, ICellStyle> _cellStyles = new();

/// <summary>
/// Конструктор для записи эксель файла через NPOI
/// </summary>
/// <param name="outputFilePath">Адрес итогового файла</param>
/// <param name="rowAccessWindowSize">Количество строк, находящихся в памяти писателя</param>
public NpoiXlsFileWriter(string outputFilePath, ILogger logger, int rowAccessWindowSize = 100)
{
_outputFilePath = outputFilePath;
_logger = logger;
_workbook = new SXSSFWorkbook(rowAccessWindowSize);
_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<CellData> 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<CellData> 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 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()
{
}

/// <summary>
/// Записываем данные в файл и закрываем стрим.
/// </summary>
public void Dispose()
{
_fileStream = File.Open(_outputFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
_workbook.Write(_fileStream);
_fileStream.Close();
}
}
Loading

0 comments on commit b3add8f

Please sign in to comment.