This commit is contained in:
melekhin
2026-06-08 14:31:31 +07:00
parent f9cca53f75
commit f5eb667973
36 changed files with 159 additions and 41 deletions

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
internal static class CellAddressHelper internal static class CellAddressHelper
{ {

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Определяет выравнивание содержимого ячейки: горизонтальное, вертикальное, перенос текста и уменьшение по размеру. /// Определяет выравнивание содержимого ячейки: горизонтальное, вертикальное, перенос текста и уменьшение по размеру.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Определяет границы ячейки: верхнюю, нижнюю, левую, правую и диагональные. /// Определяет границы ячейки: верхнюю, нижнюю, левую, правую и диагональные.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Определяет заливку (фон) ячейки. /// Определяет заливку (фон) ячейки.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Определяет шрифтовое оформление всей ячейки: размер, семейство, цвет, начертание. /// Определяет шрифтовое оформление всей ячейки: размер, семейство, цвет, начертание.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors namespace QWERTYkez.ExcelProcessor
{ {
/// <summary> /// <summary>
/// Представляет ширину столбца в Excel. Поддерживает задание в символах, пунктах, сантиметрах и миллиметрах. /// Представляет ширину столбца в Excel. Поддерживает задание в символах, пунктах, сантиметрах и миллиметрах.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
public readonly struct ExColor(System.Drawing.Color? Color) public readonly struct ExColor(System.Drawing.Color? Color)
{ {
@@ -59,4 +59,24 @@ public readonly struct ExColor(System.Drawing.Color? Color)
} }
return excelColor; return excelColor;
} }
public static ExColor FromRgb(string rgb)
{
if (string.IsNullOrEmpty(rgb)) return new ExColor(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 new ExColor(System.Drawing.Color.FromArgb(r, g, b));
}
else if (rgb.Length == 8)
{
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 new ExColor(System.Drawing.Color.FromArgb(r, g, b));
}
return new ExColor(null);
}
} }

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="IBook"/>, которая делегирует вызовы к <see cref="ExcelWriter"/>. /// Внутренняя реализация <see cref="IBook"/>, которая делегирует вызовы к <see cref="ExcelWriter"/>.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="ICell"/>. /// Внутренняя реализация <see cref="ICell"/>.
@@ -390,7 +390,7 @@ internal sealed class ExcelCell : ICell
} }
} }
public ICell Set(Action<ICellText> value) public ICell Text(Action<ICellText> value)
{ {
if (value == null) return this; if (value == null) return this;
_writer.ThrowIfDisposed(); _writer.ThrowIfDisposed();
@@ -425,6 +425,39 @@ internal sealed class ExcelCell : ICell
return this; return this;
} }
/// <inheritdoc />
public ICellText? Text()
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var cell = GetCellElement();
if (cell == null || cell.DataType?.Value != CellValues.InlineString || cell.InlineString == null)
return null;
var textObj = new ExcelCellText();
foreach (var run in cell.InlineString.Elements<Run>())
{
string text = run.GetFirstChild<Text>()?.Text ?? string.Empty;
RunFormat? format = null;
if (run.RunProperties != null)
{
// Преобразуем RunProperties в RunFormat (можно вынести в отдельный метод)
format = RunFormat.FromRunProperties(run.RunProperties);
}
textObj.AddRun(text, format);
}
return textObj;
}
}
/// <inheritdoc />
public bool TryText(out ICellText cellText)
{
cellText = Text()!;
return cellText is not null;
}
public ICell Set(string value) public ICell Set(string value)
{ {
if (value == null) return this; if (value == null) return this;

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="ICellText"/> для работы с богатым текстом ячейки. /// Внутренняя реализация <see cref="ICellText"/> для работы с богатым текстом ячейки.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="IColumn"/>. /// Внутренняя реализация <see cref="IColumn"/>.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="IRange"/>. /// Внутренняя реализация <see cref="IRange"/>.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="IRow"/>. /// Внутренняя реализация <see cref="IRow"/>.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="IRun"/> для хранения форматированного фрагмента текста. /// Внутренняя реализация <see cref="IRun"/> для хранения форматированного фрагмента текста.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Внутренняя реализация <see cref="ISheet"/>. /// Внутренняя реализация <see cref="ISheet"/>.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary>Представляет книгу Excel</summary> /// <summary>Представляет книгу Excel</summary>
public interface IBook public interface IBook
@@ -700,7 +700,13 @@ public interface ICell
ICell Set(CellFont format); ICell Set(CellFont format);
/// <summary>Устанавливает богатый текст (форматированный) с помощью делегата.</summary> /// <summary>Устанавливает богатый текст (форматированный) с помощью делегата.</summary>
ICell Set(Action<ICellText> value); ICell Text(Action<ICellText> value);
/// <summary>Возвращает объект для редактирования богатого текста ячейки (если ячейка содержит InlineString).</summary>
bool TryText(out ICellText cellText);
/// <summary>Возвращает объект для редактирования богатого текста ячейки (если ячейка содержит InlineString).</summary>
ICellText? Text();
/// <summary>Устанавливает простое текстовое значение (без форматирования).</summary> /// <summary>Устанавливает простое текстовое значение (без форматирования).</summary>
ICell Set(string value); ICell Set(string value);

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
public class NumberFormatPattern public class NumberFormatPattern
{ {

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Предоставляет типобезопасное представление высоты строки в Excel с поддержкой различных единиц измерения. /// Предоставляет типобезопасное представление высоты строки в Excel с поддержкой различных единиц измерения.

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
/// <summary> /// <summary>
/// Определяет форматирование отдельного фрагмента (Run) внутри ячейки с богатым текстом. /// Определяет форматирование отдельного фрагмента (Run) внутри ячейки с богатым текстом.
@@ -30,6 +30,66 @@ public readonly struct RunFormat
/// <summary>Вертикальное смещение (надстрочный или подстрочный).</summary> /// <summary>Вертикальное смещение (надстрочный или подстрочный).</summary>
public VerticalTextRunAlignment? Vertical { get; init; } 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 = rPr.GetFirstChild<Color>()?.Rgb is not null
? ExColor.FromRgb(rPr.GetFirstChild<Color>()!.Rgb!.Value!)
: null!,
FontSize = rPr.GetFirstChild<FontSize>()?.Val?.Value,
FontFamily = rPr.GetFirstChild<RunFont>()?.Val,
Vertical = vertical
};
return fmt;
}
/* /*
методы для извлечения OpenXmlElement или других более удобных типов методы для извлечения OpenXmlElement или других более удобных типов

View File

@@ -1,5 +1,4 @@
using QWERTYkez.ExcelProcessor.Editors; using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
namespace QWERTYkez.ExcelProcessor; namespace QWERTYkez.ExcelProcessor;

View File

@@ -1,6 +1,4 @@
using QWERTYkez.ExcelProcessor.Editors; namespace QWERTYkez.ExcelProcessor;
namespace QWERTYkez.ExcelProcessor;
public interface IExcelWriter : IBook public interface IExcelWriter : IBook
{ {

View File

@@ -8,7 +8,7 @@ namespace QWERTYkez.ExcelProcessor;
/// к верхнему регистру и удаляет диакритические знаки (например, 'ё' -> 'Е'). /// к верхнему регистру и удаляет диакритические знаки (например, 'ё' -> 'Е').
/// Реализует ISet&lt;string&gt;, поэтому может использоваться там, где ожидается этот интерфейс. /// Реализует ISet&lt;string&gt;, поэтому может использоваться там, где ожидается этот интерфейс.
/// </summary> /// </summary>
public class NormalizedSet : ISet<string> internal class NormalizedSet : ISet<string>
{ {
private readonly HashSet<string> _inner; private readonly HashSet<string> _inner;

View File

@@ -5,10 +5,11 @@
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn>1701;1702;IDE0130</NoWarn>
<!-- NuGet --> <!-- NuGet -->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>0.9.0</Version> <Version>0.9.1</Version>
<Authors>QWERTYkez</Authors> <Authors>QWERTYkez</Authors>
<Company>QWERTYkez</Company> <Company>QWERTYkez</Company>
<Description>OpenXml Processor library for Excel</Description> <Description>OpenXml Processor library for Excel</Description>

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.WordProcessor.Builders; namespace QWERTYkez.WordProcessor;
public readonly struct CellProps(double? width = null!) public readonly struct CellProps(double? width = null!)
{ {

View File

@@ -1,7 +1,7 @@
using MathStyle = DocumentFormat.OpenXml.Math.Style; using MathStyle = DocumentFormat.OpenXml.Math.Style;
using MathStyleValues = DocumentFormat.OpenXml.Math.StyleValues; using MathStyleValues = DocumentFormat.OpenXml.Math.StyleValues;
namespace QWERTYkez.WordProcessor.Builders; namespace QWERTYkez.WordProcessor;
public record FontProps public record FontProps
{ {

View File

@@ -17,7 +17,7 @@ using SubSuperscript = DocumentFormat.OpenXml.Math.SubSuperscript;
using SuperArgument = DocumentFormat.OpenXml.Math.SuperArgument; using SuperArgument = DocumentFormat.OpenXml.Math.SuperArgument;
using Superscript = DocumentFormat.OpenXml.Math.Superscript; using Superscript = DocumentFormat.OpenXml.Math.Superscript;
namespace QWERTYkez.WordProcessor.Builders; namespace QWERTYkez.WordProcessor;
internal static class FormulaHelper internal static class FormulaHelper
{ {

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.WordProcessor.Builders; namespace QWERTYkez.WordProcessor;
public interface ITable public interface ITable
{ {

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.WordProcessor.Builders; namespace QWERTYkez.WordProcessor;
abstract class ParagraphBuilderBase : IParagraph, IFormula abstract class ParagraphBuilderBase : IParagraph, IFormula
{ {

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.WordProcessor.Builders; namespace QWERTYkez.WordProcessor;
internal sealed class TableBuilder : ParagraphBuilderBase, ITable, IRow, ICell internal sealed class TableBuilder : ParagraphBuilderBase, ITable, IRow, ICell
{ {

View File

@@ -1,4 +1,4 @@
namespace QWERTYkez.WordProcessor.Builders; namespace QWERTYkez.WordProcessor;
internal sealed class TextBuilder : ParagraphBuilderBase, IText internal sealed class TextBuilder : ParagraphBuilderBase, IText
{ {

View File

@@ -1,4 +1,4 @@
using QWERTYkez.WordProcessor.Builders; using QWERTYkez.WordProcessor;
namespace QWERTYkez.WordProcessor; namespace QWERTYkez.WordProcessor;

View File

@@ -8,7 +8,7 @@ namespace QWERTYkez.WordProcessor;
/// к верхнему регистру и удаляет диакритические знаки (например, 'ё' -> 'Е'). /// к верхнему регистру и удаляет диакритические знаки (например, 'ё' -> 'Е').
/// Реализует ISet&lt;string&gt;, поэтому может использоваться там, где ожидается этот интерфейс. /// Реализует ISet&lt;string&gt;, поэтому может использоваться там, где ожидается этот интерфейс.
/// </summary> /// </summary>
public class NormalizedSet : ISet<string> internal class NormalizedSet : ISet<string>
{ {
private readonly HashSet<string> _inner; private readonly HashSet<string> _inner;

View File

@@ -5,10 +5,11 @@
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn>1701;1702;IDE0130</NoWarn>
<!-- NuGet --> <!-- NuGet -->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>0.9.0</Version> <Version>0.9.1</Version>
<Authors>QWERTYkez</Authors> <Authors>QWERTYkez</Authors>
<Company>QWERTYkez</Company> <Company>QWERTYkez</Company>
<Description>OpenXml Processor library for Word</Description> <Description>OpenXml Processor library for Word</Description>

View File

@@ -1,4 +1,4 @@
using QWERTYkez.WordProcessor.Builders; using QWERTYkez.WordProcessor;
namespace QWERTYkez.WordProcessor; namespace QWERTYkez.WordProcessor;

View File

@@ -1,4 +1,4 @@
using QWERTYkez.WordProcessor.Builders; using QWERTYkez.WordProcessor;
namespace QWERTYkez.WordProcessor; namespace QWERTYkez.WordProcessor;

View File

@@ -1,4 +1,4 @@
using QWERTYkez.WordProcessor.Builders; using QWERTYkez.WordProcessor;
namespace QWERTYkez.WordProcessor; namespace QWERTYkez.WordProcessor;