CellAddress для замены tuple;

XLExtentions методы расширения для назначения и форматирования значений;
SheetBlockAbstract для блоков рапорта;
This commit is contained in:
ngfrolov 2022-06-23 18:04:01 +05:00
parent 9a3ac58219
commit fce7482d1b
3 changed files with 181 additions and 0 deletions

View File

@ -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();
}
}

View File

@ -0,0 +1,11 @@
using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport
{
internal abstract class SheetBlockAbstract
{
public abstract CellAddress Draw(IXLWorksheet sheet, CellAddress startPoint);
}
}

View File

@ -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;
}
}
}