Files
QWERTYkez.OpenXmlProcessors/QWERTYkez.ExcelProcessor/Editors/RunFormat.cs
melekhin e373d4108a
All checks were successful
Publish NuGet packages / publish (push) Successful in 28s
many debugs
2026-06-19 15:06:40 +07:00

167 lines
6.0 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;
/// <summary>
/// Определяет форматирование отдельного фрагмента (Run) внутри ячейки с богатым текстом.
/// Применяется только к тексту внутри <see cref="ICellText"/>.
/// </summary>
public readonly struct RunFormat
{
/// <summary>Жирное начертание фрагмента.</summary>
public bool? IsBold { get; init; }
/// <summary>Курсив фрагмента.</summary>
public bool? IsItalic { get; init; }
/// <summary>Стиль подчёркивания (одинарное, двойное, волнистое и т.д.).</summary>
public UnderlineStyle? Underline { get; init; }
/// <summary>Одинарное зачёркивание.</summary>
public bool? IsStrike { get; init; }
/// <summary>Цвет текста фрагмента.</summary>
public System.Drawing.Color? Color { get; init; }
/// <summary>Размер шрифта фрагмента в пунктах.</summary>
public double? FontSize { get; init; }
/// <summary>Имя шрифта фрагмента (например, "Calibri").</summary>
public string? FontFamily { get; init; }
/// <summary>Вертикальное смещение (надстрочный или подстрочный).</summary>
public VerticalTextRunAlignment? Vertical { get; init; }
public static RunFormat? FromRunProperties(RunProperties rPr)
{
UnderlineStyle? underline;
if (rPr.GetFirstChild<Underline>()?.Val?.Value is { } underlineVal)
{
if (underlineVal == UnderlineValues.Single)
{
underline = UnderlineStyle.Single;
}
else if (underlineVal == UnderlineValues.Double)
{
underline = UnderlineStyle.Double;
}
else if (underlineVal == UnderlineValues.SingleAccounting)
{
underline = UnderlineStyle.SingleAccounting;
}
else if (underlineVal == UnderlineValues.DoubleAccounting)
{
underline = UnderlineStyle.DoubleAccounting;
}
else underline = null!;
}
else underline = null!;
VerticalTextRunAlignment? vertical;
if (rPr.GetFirstChild<VerticalTextAlignment>()?.Val?.Value is { } verticalVal)
{
if (verticalVal == VerticalAlignmentRunValues.Superscript)
{
vertical = VerticalTextRunAlignment.Superscript;
}
else if (verticalVal == VerticalAlignmentRunValues.Subscript)
{
vertical = VerticalTextRunAlignment.Subscript;
}
else vertical = null!;
}
else vertical = null!;
if (rPr == null) return null;
var fmt = new RunFormat
{
IsBold = rPr.GetFirstChild<Bold>() != null,
IsItalic = rPr.GetFirstChild<Italic>() != null,
IsStrike = rPr.GetFirstChild<Strike>() != null,
// DoubleStrike в Excel не поддерживается, опускаем
Underline = underline,
Color = FromExcelColor(rPr.GetFirstChild<Color>()?.Rgb),
FontSize = rPr.GetFirstChild<FontSize>()?.Val?.Value,
FontFamily = rPr.GetFirstChild<RunFont>()?.Val,
Vertical = vertical
};
return fmt;
}
static System.Drawing.Color? FromExcelColor(string? rgb)
{
if (string.IsNullOrWhiteSpace(rgb)) return null;
if (rgb!.Length == 6)
{
byte r = Convert.ToByte(rgb.Substring(0, 2), 16);
byte g = Convert.ToByte(rgb.Substring(2, 2), 16);
byte b = Convert.ToByte(rgb.Substring(4, 2), 16);
return System.Drawing.Color.FromArgb(r, g, b);
}
else if (rgb.Length == 8)
{
byte a = Convert.ToByte(rgb.Substring(0, 2), 16);
byte r = Convert.ToByte(rgb.Substring(2, 2), 16);
byte g = Convert.ToByte(rgb.Substring(4, 2), 16);
byte b = Convert.ToByte(rgb.Substring(6, 2), 16);
return System.Drawing.Color.FromArgb(a, r, g, b);
}
else return null;
}
public bool TryGetExcelColor(out Color excelColor)
{
if (Color is { } c)
{
excelColor = new Color() { Rgb = $"{c.R:X2}{c.G:X2}{c.B:X2}" };
return true;
}
else
{
excelColor = null!;
return false;
}
}
/*
методы для извлечения OpenXmlElement или других более удобных типов
public bool TryExtract(out List<...> elements);
или
public bool TrySetFor(InlineString str)
или
public bool TrySetFor(ExcelRun str)
*/
}
/// <summary>Определяет стиль подчёркивания текста в ячейке или в части текста (Run).</summary>
public enum UnderlineStyle
{
/// <summary>Одинарное сплошное подчёркивание.</summary>
Single,
/// <summary>Двойное сплошное подчёркивание.</summary>
Double,
/// <summary>Одинарное подчёркивание, используемое для бухгалтерских форматов (нижняя граница ячейки).</summary>
SingleAccounting,
/// <summary>Двойное подчёркивание для бухгалтерских форматов.</summary>
DoubleAccounting
}
/// <summary>Вертикальное смещение текста внутри прогона (Run) надстрочный или подстрочный.</summary>
public enum VerticalTextRunAlignment
{
/// <summary>Надстрочный текст (верхний индекс).</summary>
Superscript,
/// <summary>Подстрочный текст (нижний индекс).</summary>
Subscript
}