From b6868342361db8e86ea5a56152673ed185b11cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 7 Feb 2024 07:40:00 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20=D1=80?= =?UTF-8?q?=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BF=D0=B0=D1=80=D1=81=D0=B8=D0=BD=D0=B3=D0=B0?= =?UTF-8?q?=20excel=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AsbCloudInfrastructure.csproj | 2 +- AsbCloudInfrastructure/XLExtentions.cs | 112 ++++-------- AsbCloudWebApi.Tests/XLExtensionsTests.cs | 159 ++++++++++++++++++ 3 files changed, 191 insertions(+), 82 deletions(-) create mode 100644 AsbCloudWebApi.Tests/XLExtensionsTests.cs diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj index 02400268..cdb57ae5 100644 --- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj +++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj @@ -53,7 +53,7 @@ - + diff --git a/AsbCloudInfrastructure/XLExtentions.cs b/AsbCloudInfrastructure/XLExtentions.cs index e633a875..0aeeca00 100644 --- a/AsbCloudInfrastructure/XLExtentions.cs +++ b/AsbCloudInfrastructure/XLExtentions.cs @@ -1,96 +1,46 @@ using ClosedXML.Excel; using System; -using System.Globalization; using System.IO; +using System.Linq; namespace AsbCloudInfrastructure; -internal static class XLExtentions +public static class XLExtentions { - internal static IXLCell _SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS", bool setAllBorders = true) - { - cell.Value = value; - if (setAllBorders == true) - { - cell.Style - .SetAllBorders() - .Alignment.WrapText = true; - } + public static IXLWorksheet GetWorksheet(this IXLWorkbook workbook, string sheetName) => + workbook.Worksheets.FirstOrDefault(ws => string.Equals(ws.Name.Trim(), sheetName.Trim(), StringComparison.CurrentCultureIgnoreCase)) + ?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}."); + public static IXLCell SetCellValue(this IXLCell cell, T value) + { + if (typeof(T) == typeof(DateTime)) + cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS"; - cell.Value = value; + cell.Value = XLCellValue.FromObject(value); - cell.DataType = XLDataType.DateTime; - cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS"; + return cell; + } - return cell; - } + public static IXLCell SetHyperlink(this IXLCell cell, string link) + { + cell.SetHyperlink(new XLHyperlink(link)); - public static IXLCell SetVal(this IXLCell cell, double? value, string format = "0.00") - { - cell.Value = (value is not null && double.IsFinite(value.Value)) ? value : null; - cell.DataType = XLDataType.Number; - cell.Style.NumberFormat.Format = format; - return cell; - } + return cell; + } - public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false) - { - cell.Value = value; - if (adaptRowHeight) - { - var colWidth = cell.WorksheetColumn().Width; - var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize); - if (value.Length > maxCharsToWrap) - { - var row = cell.WorksheetRow(); - var baseHeight = row.Height; - row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); - } - } + public static T? GetCellValue(this IXLCell cell) + { + try + { + if (cell.IsEmpty() && default(T) == null) + return default; - return cell; - } - - public static IXLCell SetVal(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS") - { - cell.Value = value; - cell.DataType = XLDataType.DateTime; - cell.Style.DateFormat.Format = dateFormat; - - return cell; - } - - private static IXLStyle SetAllBorders(this IXLStyle style, XLBorderStyleValues borderStyle = XLBorderStyleValues.Thin) - { - style.Border.RightBorder = borderStyle; - style.Border.LeftBorder = borderStyle; - style.Border.TopBorder = borderStyle; - style.Border.BottomBorder = borderStyle; - style.Border.InsideBorder = borderStyle; - style.Border.OutsideBorder = borderStyle; - return style; - } - - internal static T? GetCellValue(this IXLCell cell) - { - try - { - if (cell.IsEmpty() && default(T) == null) - return default; - - if (typeof(T) != typeof(DateTime)) - return (T)Convert.ChangeType(cell.GetFormattedString(), typeof(T), CultureInfo.InvariantCulture); - - if (cell.Value is DateTime dateTime) - return (T)(object)dateTime; - - return (T)(object)DateTime.FromOADate((double)cell.Value); - } - catch - { - throw new FileFormatException( - $"Лист '{cell.Worksheet.Name}'. {cell.Address.RowNumber} строка содержит некорректное значение в {cell.Address.ColumnNumber} столбце"); - } - } + return cell.GetValue(); + } + catch + { + throw new FileFormatException( + $"Лист '{cell.Worksheet.Name}'. {cell.Address.RowNumber} строка содержит некорректное значение в {cell.Address.ColumnNumber} столбце"); + } + } } \ No newline at end of file diff --git a/AsbCloudWebApi.Tests/XLExtensionsTests.cs b/AsbCloudWebApi.Tests/XLExtensionsTests.cs new file mode 100644 index 00000000..7f5fd781 --- /dev/null +++ b/AsbCloudWebApi.Tests/XLExtensionsTests.cs @@ -0,0 +1,159 @@ +using System; +using AsbCloudInfrastructure; +using ClosedXML.Excel; +using Xunit; + +namespace AsbCloudWebApi.Tests; + +public class XLExtensionsTests +{ + private const string cellUsed = "A1"; + private const string sheetName = "test"; + + private readonly IXLWorkbook workbook; + + public XLExtensionsTests() + { + workbook = new XLWorkbook(); + workbook.Worksheets.Add(sheetName); + } + + [Fact] + public void GetWorksheet_returns_sheet() + { + //act + var sheet = workbook.GetWorksheet(sheetName); + + //assert + Assert.NotNull(sheet); + } + + [Theory] + [MemberData(nameof(valueTypesToSet))] + public void SetCellValue_returns_success(object value, XLDataType expectedDataType) + { + //act + var cell = GetCell(cellUsed); + cell.SetCellValue(value); + + //assert + Assert.Equal(expectedDataType, cell.DataType); + } + + [Fact] + public void GetCellValue_returns_double() + { + //arrange + const double expectedValue = 2.0d; + SetCellValue(expectedValue); + + //act + var actualValue = GetCell(cellUsed).GetCellValue(); + + //assert + Assert.Equal(expectedValue, actualValue); + } + + [Fact] + public void GetCellValue_returns_float() + { + //arrange + const float expectedValue = 2.0f; + SetCellValue(expectedValue); + + //act + var actualValue = GetCell(cellUsed).GetCellValue(); + + //assert + Assert.Equal(expectedValue, actualValue); + } + + [Theory] + [InlineData("test")] + [InlineData(null)] + public void GetCellValue_returns_string(string? expectedValue) + { + //arrange + SetCellValue(expectedValue); + + //act + var actualValue = GetCell(cellUsed).GetCellValue(); + + //assert + Assert.Equal(expectedValue, actualValue); + } + + [Fact] + public void GetCellValue_returns_bool() + { + //arrange + const bool expectedValue = true; + SetCellValue(expectedValue); + + //act + var actualValue = GetCell(cellUsed).GetCellValue(); + + //assert + Assert.Equal(expectedValue, actualValue); + } + + [Fact] + public void GetCellValue_returns_dateTime() + { + //arrange + var expectedValue = DateTime.Parse("2023-01-01"); + SetCellValue(expectedValue); + + //act + var actualValue = GetCell(cellUsed).GetCellValue(); + + //assert + Assert.Equal(expectedValue, actualValue); + Assert.Equal(DateTimeKind.Unspecified, actualValue.Kind); + } + + [Fact] + public void GetCellValue_returns_nullable() + { + //act + var actualValue = GetCell(cellUsed).GetCellValue(); + + //assert + Assert.Null(actualValue); + } + + [Fact] + public void SetHyperlink_returns_success() + { + //arrange + const string link = "http://test.ru"; + + //act + GetCell(cellUsed).SetHyperlink(link); + + //assert + var hyperLink = GetCell(cellUsed).GetHyperlink(); + Assert.NotNull(hyperLink); + } + + private void SetCellValue(T value) + { + var cell = GetCell(cellUsed); + cell.SetCellValue(value); + } + + public static readonly object[][] valueTypesToSet = + { + new object[] { 2.0d, XLDataType.Number }, + new object[] { 2.0f, XLDataType.Number }, + new object[] { "test", XLDataType.Text }, + new object[] { true, XLDataType.Boolean }, + new object[] { DateTime.UtcNow, XLDataType.DateTime } + }; + + private IXLCell GetCell(string cellAddressInRange) + { + var sheet = workbook.GetWorksheet(sheetName); + return sheet.Cell(cellAddressInRange); + } +} \ No newline at end of file