2022-06-24 11:03:13 +05:00
|
|
|
|
using ClosedXML.Excel;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
|
using System.Text;
|
2022-06-23 18:04:01 +05:00
|
|
|
|
|
|
|
|
|
namespace AsbCloudInfrastructure.Services.DailyReport
|
|
|
|
|
{
|
2022-06-24 11:03:13 +05:00
|
|
|
|
internal class CellAddress: IXLAddress
|
2022-06-23 18:04:01 +05:00
|
|
|
|
{
|
2022-06-24 11:03:13 +05:00
|
|
|
|
const int excelLettersCount = 'Z' - 'A' + 1;
|
|
|
|
|
public int RowNumber { get; set; }
|
|
|
|
|
public int ColumnNumber { get; set; }
|
|
|
|
|
|
|
|
|
|
public string ColumnLetter
|
|
|
|
|
{
|
|
|
|
|
get { return CalcColumnLetter(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool FixedColumn { get; set; }
|
|
|
|
|
|
|
|
|
|
public bool FixedRow { get; set; }
|
|
|
|
|
|
|
|
|
|
public string UniqueId => ToString(XLReferenceStyle.A1, true);
|
|
|
|
|
|
|
|
|
|
public IXLWorksheet Worksheet { get; set; }
|
2022-06-23 18:04:01 +05:00
|
|
|
|
|
|
|
|
|
public CellAddress(int row, int colunm)
|
|
|
|
|
{
|
2022-06-24 11:03:13 +05:00
|
|
|
|
RowNumber = row;
|
|
|
|
|
ColumnNumber = colunm;
|
2022-06-23 18:04:01 +05:00
|
|
|
|
}
|
2022-06-24 11:03:13 +05:00
|
|
|
|
|
2022-06-23 18:04:01 +05:00
|
|
|
|
public static CellAddress operator + (CellAddress a, CellAddress b)
|
2022-06-24 11:03:13 +05:00
|
|
|
|
=> new CellAddress(a.RowNumber + b.RowNumber, a.ColumnNumber + b.ColumnNumber);
|
|
|
|
|
public static CellAddress operator +(CellAddress a, (int row, int column) b)
|
|
|
|
|
=> new CellAddress(a.RowNumber + b.row, a.ColumnNumber + b.column);
|
2022-06-23 18:04:01 +05:00
|
|
|
|
public static CellAddress operator - (CellAddress a, CellAddress b)
|
2022-06-24 11:03:13 +05:00
|
|
|
|
=> new CellAddress(a.RowNumber - b.RowNumber, a.ColumnNumber - b.ColumnNumber);
|
2022-06-23 18:04:01 +05:00
|
|
|
|
public static bool operator == (CellAddress a, CellAddress b)
|
2022-06-24 11:03:13 +05:00
|
|
|
|
=> a.RowNumber == b.RowNumber && a.ColumnNumber == b.ColumnNumber;
|
2022-06-23 18:04:01 +05:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 11:03:13 +05:00
|
|
|
|
private string CalcColumnLetter()
|
2022-06-23 18:04:01 +05:00
|
|
|
|
{
|
|
|
|
|
string letter = "";
|
|
|
|
|
|
2022-06-24 11:03:13 +05:00
|
|
|
|
while (ColumnNumber > 0)
|
2022-06-23 18:04:01 +05:00
|
|
|
|
{
|
2022-06-24 11:03:13 +05:00
|
|
|
|
int modulo = (ColumnNumber - 1) % excelLettersCount;
|
2022-06-23 18:04:01 +05:00
|
|
|
|
letter = Convert.ToChar('A' + modulo) + letter;
|
2022-06-24 11:03:13 +05:00
|
|
|
|
ColumnNumber = (ColumnNumber - modulo) / excelLettersCount;
|
2022-06-23 18:04:01 +05:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 11:03:13 +05:00
|
|
|
|
return letter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public CellAddress Copy()
|
|
|
|
|
=> new CellAddress(this.RowNumber, this.ColumnNumber);
|
|
|
|
|
|
|
|
|
|
public string ToString(XLReferenceStyle referenceStyle)
|
|
|
|
|
=> ToString(referenceStyle, false);
|
|
|
|
|
|
|
|
|
|
public string ToString(XLReferenceStyle referenceStyle, bool includeSheet)
|
|
|
|
|
{
|
|
|
|
|
if (referenceStyle == XLReferenceStyle.R1C1)
|
|
|
|
|
throw new NotImplementedException("R1C1 - style doesn't implemented");
|
|
|
|
|
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
if (includeSheet && Worksheet is not null)
|
|
|
|
|
sb.Append('$')
|
|
|
|
|
.Append(Worksheet.Name)
|
|
|
|
|
.Append('.');
|
|
|
|
|
|
|
|
|
|
if (FixedColumn)
|
|
|
|
|
sb.Append('$');
|
|
|
|
|
|
|
|
|
|
sb.Append(ColumnLetter);
|
|
|
|
|
|
|
|
|
|
if (FixedRow)
|
|
|
|
|
sb.Append('$');
|
|
|
|
|
|
|
|
|
|
sb.Append(RowNumber);
|
|
|
|
|
|
|
|
|
|
return sb.ToString();
|
2022-06-23 18:04:01 +05:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 11:03:13 +05:00
|
|
|
|
public string ToStringFixed()
|
|
|
|
|
=> ToStringFixed(XLReferenceStyle.A1);
|
|
|
|
|
|
|
|
|
|
public string ToStringFixed(XLReferenceStyle referenceStyle)
|
|
|
|
|
=> ToStringFixed(referenceStyle, false);
|
|
|
|
|
|
|
|
|
|
public string ToStringFixed(XLReferenceStyle referenceStyle, bool includeSheet)
|
|
|
|
|
{
|
|
|
|
|
if (referenceStyle == XLReferenceStyle.R1C1)
|
|
|
|
|
throw new NotImplementedException("R1C1 - style doesn't implemented");
|
|
|
|
|
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
if (includeSheet && Worksheet is not null)
|
|
|
|
|
sb.Append('$')
|
|
|
|
|
.Append(Worksheet.Name)
|
|
|
|
|
.Append('.');
|
|
|
|
|
|
|
|
|
|
sb.Append('$');
|
|
|
|
|
sb.Append(ColumnLetter);
|
|
|
|
|
sb.Append('$');
|
|
|
|
|
sb.Append(RowNumber);
|
|
|
|
|
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string ToStringRelative()
|
|
|
|
|
=> ToStringRelative(false);
|
|
|
|
|
|
|
|
|
|
public string ToStringRelative(bool includeSheet)
|
|
|
|
|
{
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
if (includeSheet && Worksheet is not null)
|
|
|
|
|
sb.Append('$')
|
|
|
|
|
.Append(Worksheet.Name)
|
|
|
|
|
.Append('.');
|
|
|
|
|
|
|
|
|
|
sb.Append(ColumnLetter);
|
|
|
|
|
sb.Append(RowNumber);
|
|
|
|
|
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Equals(IXLAddress x, IXLAddress y)
|
|
|
|
|
=> x.ColumnNumber == y.ColumnNumber &&
|
|
|
|
|
x.RowNumber == y.RowNumber &&
|
|
|
|
|
x.FixedColumn == y.FixedColumn &&
|
|
|
|
|
x.FixedRow == y.FixedRow &&
|
|
|
|
|
x.Worksheet == y.Worksheet;
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
=> base.GetHashCode();
|
|
|
|
|
|
|
|
|
|
public int GetHashCode([DisallowNull] IXLAddress obj)
|
|
|
|
|
=> obj.GetHashCode();
|
|
|
|
|
|
|
|
|
|
public bool Equals(IXLAddress other)
|
|
|
|
|
=> Equals(this, other);
|
|
|
|
|
|
2022-06-23 18:04:01 +05:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|