Files
QWERTYkez.OpenXmlProcessors/QWERTYkez.ExcelProcessor/Editors/CellAlign.cs
2026-06-05 15:58:03 +07:00

223 lines
8.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace QWERTYkez.ExcelProcessor.Editors;
/// <summary>
/// Определяет выравнивание содержимого ячейки: горизонтальное, вертикальное, перенос текста и уменьшение по размеру.
/// Все свойства опциональны. Если свойство не задано, соответствующий аспект не изменяется.
/// </summary>
public readonly struct CellAlign : IEquatable<CellAlign>
{
/// <summary>Горизонтальное выравнивание.</summary>
public CellAlignHorizontal? Horizontal { get; init; }
/// <summary>Вертикальное выравнивание.</summary>
public CellAlignVertical? Vertical { get; init; }
/// <summary>Переносить ли текст по словам (многострочный режим).</summary>
public bool? WrapText { get; init; }
/// <summary>Уменьшать размер шрифта, чтобы текст поместился в ячейку.</summary>
public bool? ShrinkToFit { get; init; }
/// <summary>Преобразует горизонтальное выравнивание в тип Open XML.</summary>
public bool TryGetExcelHorizontalAlignment(out HorizontalAlignmentValues value)
{
if (Horizontal.HasValue)
{
value = Horizontal.Value switch
{
CellAlignHorizontal.Left => HorizontalAlignmentValues.Left,
CellAlignHorizontal.Center => HorizontalAlignmentValues.Center,
CellAlignHorizontal.Right => HorizontalAlignmentValues.Right,
CellAlignHorizontal.Fill => HorizontalAlignmentValues.Fill,
CellAlignHorizontal.Justify => HorizontalAlignmentValues.Justify,
CellAlignHorizontal.CenterContinuous => HorizontalAlignmentValues.CenterContinuous,
CellAlignHorizontal.Distributed => HorizontalAlignmentValues.Distributed,
_ => throw new NotSupportedException($"Unsupported horizontal alignment: {Horizontal.Value}")
};
return true;
}
value = default;
return false;
}
/// <summary>Преобразует вертикальное выравнивание в тип Open XML.</summary>
public bool TryGetExcelVerticalAlignment(out VerticalAlignmentValues value)
{
if (Vertical.HasValue)
{
value = Vertical.Value switch
{
CellAlignVertical.Top => VerticalAlignmentValues.Top,
CellAlignVertical.Center => VerticalAlignmentValues.Center,
CellAlignVertical.Bottom => VerticalAlignmentValues.Bottom,
CellAlignVertical.Justify => VerticalAlignmentValues.Justify,
CellAlignVertical.Distributed => VerticalAlignmentValues.Distributed,
_ => throw new NotSupportedException($"Unsupported vertical alignment: {Vertical.Value}")
};
return true;
}
value = default;
return false;
}
/// <summary>Создаёт элемент Alignment для Open XML.</summary>
public Alignment? ToAlignment()
{
if (!Horizontal.HasValue && !Vertical.HasValue && !WrapText.HasValue && !ShrinkToFit.HasValue)
return null;
var align = new Alignment();
if (TryGetExcelHorizontalAlignment(out var hAlign))
align.Horizontal = hAlign;
if (TryGetExcelVerticalAlignment(out var vAlign))
align.Vertical = vAlign;
if (WrapText.HasValue)
align.WrapText = WrapText.Value;
if (ShrinkToFit.HasValue)
align.ShrinkToFit = ShrinkToFit.Value;
return align;
}
/// <summary>Создаёт CellAlign из элемента Alignment Open XML.</summary>
public static CellAlign FromAlignment(Alignment? alignment)
{
if (alignment == null)
return default;
var result = new CellAlign();
if (alignment.Horizontal?.Value is { } horizontal)
{
result = result with { Horizontal = MapHorizontalFromExcel(horizontal) };
}
if (alignment.Vertical?.Value is { } vertical)
{
result = result with { Vertical = MapVerticalFromExcel(vertical) };
}
if (alignment.WrapText?.Value is { } wrapText)
{
result = result with { WrapText = wrapText };
}
if (alignment.ShrinkToFit?.Value is { } shrinkToFit)
{
result = result with { ShrinkToFit = shrinkToFit };
}
return result;
}
private static CellAlignHorizontal MapHorizontalFromExcel(HorizontalAlignmentValues value)
{
if (value == HorizontalAlignmentValues.Left)
{
return CellAlignHorizontal.Left;
}
else if (value == HorizontalAlignmentValues.Center)
{
return CellAlignHorizontal.Center;
}
else if (value == HorizontalAlignmentValues.Right)
{
return CellAlignHorizontal.Right;
}
else if (value == HorizontalAlignmentValues.Fill)
{
return CellAlignHorizontal.Fill;
}
else if (value == HorizontalAlignmentValues.Justify)
{
return CellAlignHorizontal.Justify;
}
else if (value == HorizontalAlignmentValues.CenterContinuous)
{
return CellAlignHorizontal.CenterContinuous;
}
else if (value == HorizontalAlignmentValues.Distributed)
{
return CellAlignHorizontal.Distributed;
}
else throw new NotSupportedException($"Unsupported horizontal alignment: {value}");
}
private static CellAlignVertical MapVerticalFromExcel(VerticalAlignmentValues value)
{
if (value == VerticalAlignmentValues.Top)
{
return CellAlignVertical.Top;
}
else if (value == VerticalAlignmentValues.Center)
{
return CellAlignVertical.Center;
}
else if (value == VerticalAlignmentValues.Bottom)
{
return CellAlignVertical.Bottom;
}
else if (value == VerticalAlignmentValues.Justify)
{
return CellAlignVertical.Justify;
}
else if (value == VerticalAlignmentValues.Distributed)
{
return CellAlignVertical.Distributed;
}
else throw new NotSupportedException($"Unsupported vertical alignment: {value}");
}
public override bool Equals(object? obj) => obj is CellAlign other && Equals(other);
public bool Equals(CellAlign other) => this == other;
public static bool operator ==(CellAlign left, CellAlign right) =>
left.Horizontal == right.Horizontal &&
left.Vertical == right.Vertical &&
left.WrapText == right.WrapText &&
left.ShrinkToFit == right.ShrinkToFit;
public static bool operator !=(CellAlign left, CellAlign right) => !(left == right);
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 31 + (Horizontal?.GetHashCode() ?? 0);
hash = hash * 31 + (Vertical?.GetHashCode() ?? 0);
hash = hash * 31 + (WrapText?.GetHashCode() ?? 0);
hash = hash * 31 + (ShrinkToFit?.GetHashCode() ?? 0);
return hash;
}
}
}
/// <summary>Горизонтальное выравнивание содержимого ячейки.</summary>
public enum CellAlignHorizontal
{
/// <summary>По левому краю.</summary>
Left,
/// <summary>По центру.</summary>
Center,
/// <summary>По правому краю.</summary>
Right,
/// <summary>Заполнение (повтор содержимого для заполнения ширины).</summary>
Fill,
/// <summary>По ширине (для многострочного текста).</summary>
Justify,
/// <summary>Центрирование по выделенным ячейкам (визуально, без объединения).</summary>
CenterContinuous,
/// <summary>Распределённый (выравнивание по ширине с пробелами).</summary>
Distributed,
}
/// <summary>Вертикальное выравнивание содержимого ячейки.</summary>
public enum CellAlignVertical
{
/// <summary>По верхнему краю.</summary>
Top,
/// <summary>По центру.</summary>
Center,
/// <summary>По нижнему краю (значение по умолчанию).</summary>
Bottom,
/// <summary>По высоте (для многострочного текста).</summary>
Justify,
/// <summary>Распределённый по вертикали.</summary>
Distributed,
}