From fce7482d1b11bd0a49326cd98353f99172eefd3c Mon Sep 17 00:00:00 2001 From: ngfrolov <ng.frolov@autodrilling.ru> Date: Thu, 23 Jun 2022 18:04:01 +0500 Subject: [PATCH] =?UTF-8?q?CellAddress=20=D0=B4=D0=BB=D1=8F=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8B=20tuple;=20XLExtentions=20=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D0=BE=D0=B4=D1=8B=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=BD=D0=B0?= =?UTF-8?q?=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=20?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9;=20SheetBlockAbstract=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=B1=D0=BB=D0=BE=D0=BA=D0=BE=D0=B2=20=D1=80=D0=B0=D0=BF=D0=BE?= =?UTF-8?q?=D1=80=D1=82=D0=B0;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/DailyReport/CellAddress.cs | 92 +++++++++++++++++++ .../DailyReport/SheetBlockAbstract.cs | 11 +++ .../Services/DailyReport/XLExtentions.cs | 78 ++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs create mode 100644 AsbCloudInfrastructure/Services/DailyReport/SheetBlockAbstract.cs create mode 100644 AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs diff --git a/AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs b/AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs new file mode 100644 index 00000000..4b2aa03a --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs @@ -0,0 +1,92 @@ +using System; + +namespace AsbCloudInfrastructure.Services.DailyReport +{ + internal class CellAddress + { + const int excelLettersCount = 'Z' - 'A'; + public int Row { get; set; } + public int Colunm { get; set; } + + public CellAddress(int row, int colunm) + { + Row = row; + Colunm = colunm; + } + + public static CellAddress operator + (CellAddress a, CellAddress b) + => new CellAddress(a.Row + b.Row, a.Colunm + b.Colunm); + public static CellAddress operator - (CellAddress a, CellAddress b) + => new CellAddress(a.Row - b.Row, a.Colunm - b.Colunm); + public static bool operator == (CellAddress a, CellAddress b) + => a.Row == b.Row && a.Colunm == b.Colunm; + public static bool operator !=(CellAddress a, CellAddress b) + => !(a == b); + + public static bool TryParse(string cellAddress, out CellAddress parsedAddress) + { + if (cellAddress.Length < 2) + { + parsedAddress = default; + return false; + } + + int row = 0; + int col = 0; + + for (int i = 0; i < cellAddress.Length; i++) + switch (cellAddress[i]) + { + case >= '0' and <= '9': + row = row * 10 + cellAddress[i] - '0'; + break; + case >= 'A' and <= 'Z': + col = col * excelLettersCount + cellAddress[i] - 'A'; + break; + case >= 'a' and <= 'z': + col = col * excelLettersCount + cellAddress[i] - 'a'; + break; + default: + parsedAddress = default; + return false; + } + parsedAddress = new CellAddress(row, col); + return true; + } + + public string ToStringA1() + { + string letter = ""; + + while (Colunm > 0) + { + int modulo = (Colunm - 1) % excelLettersCount; + letter = Convert.ToChar('A' + modulo) + letter; + Colunm = (Colunm - modulo) / excelLettersCount; + } + + return letter + Row; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj is null) + { + return false; + } + + if (obj is CellAddress address) + return this == address; + + return false; + } + + public override int GetHashCode() + => base.GetHashCode(); + } +} diff --git a/AsbCloudInfrastructure/Services/DailyReport/SheetBlockAbstract.cs b/AsbCloudInfrastructure/Services/DailyReport/SheetBlockAbstract.cs new file mode 100644 index 00000000..e9d67cce --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/SheetBlockAbstract.cs @@ -0,0 +1,11 @@ +using ClosedXML.Excel; + +namespace AsbCloudInfrastructure.Services.DailyReport +{ + + internal abstract class SheetBlockAbstract + { + public abstract CellAddress Draw(IXLWorksheet sheet, CellAddress startPoint); + + } +} diff --git a/AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs b/AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs new file mode 100644 index 00000000..5434a958 --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs @@ -0,0 +1,78 @@ +using ClosedXML.Excel; +using System; + +namespace AsbCloudInfrastructure.Services.DailyReport +{ + internal static class XLExtentions + { + public static IXLRange SetValue(this IXLRange range, object value, int maxCharsToWrap = 88) + { + range.Merge(); + range.FirstCell().SetValue(value, maxCharsToWrap); + return range; + } + + public static IXLCell SetValue(this IXLCell cell, object value) + { + cell.Value = value; + cell.Style + .SetAllBorders() + .Alignment.WrapText = true; + + if (value is string valueString && valueString.Length > maxChartsToWrap) + { + var row = cell.WorksheetRow(); + var baseHeight = row.Height; + row.Height = 0.82d * baseHeight * Math.Ceiling(1d + valueString.Length / maxChartsToWrap); + } + + if (value is DateTime) + { + cell.DataType = XLDataType.DateTime; + cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS"; + } + else if (value is IFormattable) + { + cell.DataType = XLDataType.Number; + cell.Style.NumberFormat.Format = "0.00"; + } + + return cell; + } + + public static IXLCell SetValue(this IXLCell cell, string value, bool adaptRowHeight = false) + { + cell.Value = value; + cell.Style + .SetAllBorders() + .Alignment.WrapText = true; + + cell.Value = value; + + if (adaptRowHeight) + { + var colWidth = cell.WorksheetColumn().Width; + var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize); // TODO: Подобрать коэффициент + if(value.Length > maxCharsToWrap) + { + var row = cell.WorksheetRow(); + var baseHeight = row.Height; + row.Height = 0.82d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); + } + } + + return cell; + } + + public 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; + } + } +}