namespace QWERTYkez.ExcelProcessor; /// /// Определяет форматирование отдельного фрагмента (Run) внутри ячейки с богатым текстом. /// Применяется только к тексту внутри . /// public readonly struct RunFormat { /// Жирное начертание фрагмента. public bool? IsBold { get; init; } /// Курсив фрагмента. public bool? IsItalic { get; init; } /// Стиль подчёркивания (одинарное, двойное, волнистое и т.д.). public UnderlineStyle? Underline { get; init; } /// Одинарное зачёркивание. public bool? IsStrike { get; init; } /// Цвет текста фрагмента. public System.Drawing.Color? Color { get; init; } /// Размер шрифта фрагмента в пунктах. public double? FontSize { get; init; } /// Имя шрифта фрагмента (например, "Calibri"). public string? FontFamily { get; init; } /// Вертикальное смещение (надстрочный или подстрочный). public VerticalTextRunAlignment? Vertical { get; init; } public static RunFormat? FromRunProperties(RunProperties rPr) { UnderlineStyle? underline; if (rPr.GetFirstChild()?.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()?.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() != null, IsItalic = rPr.GetFirstChild() != null, IsStrike = rPr.GetFirstChild() != null, // DoubleStrike в Excel не поддерживается, опускаем Underline = underline, Color = FromExcelColor(rPr.GetFirstChild()?.Rgb), FontSize = rPr.GetFirstChild()?.Val?.Value, FontFamily = rPr.GetFirstChild()?.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) */ } /// Определяет стиль подчёркивания текста в ячейке или в части текста (Run). public enum UnderlineStyle { /// Одинарное сплошное подчёркивание. Single, /// Двойное сплошное подчёркивание. Double, /// Одинарное подчёркивание, используемое для бухгалтерских форматов (нижняя граница ячейки). SingleAccounting, /// Двойное подчёркивание для бухгалтерских форматов. DoubleAccounting } /// Вертикальное смещение текста внутри прогона (Run) – надстрочный или подстрочный. public enum VerticalTextRunAlignment { /// Надстрочный текст (верхний индекс). Superscript, /// Подстрочный текст (нижний индекс). Subscript }