Files
QWERTYkez.OpenXmlProcessors/QWERTYkez.WordProcessor/Builders/TableBuilder.cs
T

328 lines
8.8 KiB
C#
Raw Normal View History

2026-06-08 14:31:31 +07:00
namespace QWERTYkez.WordProcessor;
2026-06-05 15:58:03 +07:00
internal sealed class TableBuilder : ParagraphBuilderBase, ITable, IRow, ICell
{
private readonly Table _table = new();
internal TableBuilder(FontProps? baseFont) : base(baseFont)
{
}
internal static TableBuilder Create(FontProps? baseFont = null) => new(baseFont);
// Метод завершения сборки
public Table Build() => _table;
// Публичные методы настройки таблицы
public ITable Properties(
uint borderWidth = 8,
BorderValues? borderValues = null,
TableRowAlignmentValues? tableAlignment = null)
{
var borderType = borderValues ?? BorderValues.Single;
var alignment = tableAlignment ?? TableRowAlignmentValues.Center;
_table.AppendChild(new TableProperties(
new TableBorders(
new TopBorder() { Val = borderType, Size = borderWidth },
new BottomBorder() { Val = borderType, Size = borderWidth },
new LeftBorder() { Val = borderType, Size = borderWidth },
new RightBorder() { Val = borderType, Size = borderWidth },
new InsideHorizontalBorder() { Val = borderType, Size = borderWidth },
new InsideVerticalBorder() { Val = borderType, Size = borderWidth }
),
new TableJustification { Val = alignment },
new TableLayout() { Type = TableLayoutValues.Autofit }
));
return this;
}
// Добавление строк с использованием IRowBuilder
2026-09-02 16:42:34 +07:00
public ITable Row(Action<IRow> configure)
2026-06-05 15:58:03 +07:00
{
var IRowBuilder = RowBuilder;
configure(this);
_table.AppendChild(IRowBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public ITable Row(double height, Action<IRow> configure)
2026-06-05 15:58:03 +07:00
{
var IRowBuilder = RowBuilder.SetHeight(height);
configure(this);
_table.AppendChild(IRowBuilder.Build());
return this;
}
// Быстрые методы для добавления строк с ячейками
2026-09-02 16:42:34 +07:00
public ITable RowWithCells(params string[] cellTexts)
2026-06-05 15:58:03 +07:00
{
2026-09-02 16:42:34 +07:00
Row(row =>
2026-06-05 15:58:03 +07:00
{
foreach (var text in cellTexts)
{
2026-09-02 16:42:34 +07:00
row.Cell(text);
2026-06-05 15:58:03 +07:00
}
});
return this;
}
2026-09-02 16:42:34 +07:00
public ITable RowWithCells(FontProps font, params string[] cellTexts)
2026-06-05 15:58:03 +07:00
{
2026-09-02 16:42:34 +07:00
Row(row =>
2026-06-05 15:58:03 +07:00
{
foreach (var text in cellTexts)
{
2026-09-02 16:42:34 +07:00
row.Cell(text, font);
2026-06-05 15:58:03 +07:00
}
});
return this;
}
private TableRow _row = null!;
internal IRow RowBuilder
{
get
{
_row = new();
return this;
}
}
TableRow IRow.Build() => _row;
// Настройка высоты строки (исправленный метод)
public IRow SetHeight(double heightInCm)
{
var height = new TableRowHeight
{
Val = (UInt32Value)(uint)(heightInCm * 567), // 1 см = 567 DXA
HeightType = HeightRuleValues.AtLeast
};
// Убедимся, что TableRowProperties существует
if (_row.TableRowProperties is null)
{
_row.TableRowProperties = new TableRowProperties();
}
else
{
// Удалим существующий TableRowHeight, если он есть
var existingHeight = _row.TableRowProperties.Elements<TableRowHeight>().FirstOrDefault();
existingHeight?.Remove();
}
// Добавляем TableRowHeight как дочерний элемент
_row.TableRowProperties.AppendChild(height);
return this;
}
public IRow SetExactHeight(double heightInCm)
{
var height = new TableRowHeight
{
Val = (UInt32Value)(uint)(heightInCm * 567),
HeightType = HeightRuleValues.Exact
};
// Убедимся, что TableRowProperties существует
if (_row.TableRowProperties is null)
{
_row.TableRowProperties = new TableRowProperties();
}
else
{
// Удалим существующий TableRowHeight, если он есть
var existingHeight = _row.TableRowProperties.Elements<TableRowHeight>().FirstOrDefault();
existingHeight?.Remove();
}
// Добавляем TableRowHeight как дочерний элемент
_row.TableRowProperties.AppendChild(height);
return this;
}
// Добавление ячеек
2026-09-02 16:42:34 +07:00
public IRow Cell(Action<ICell> configure)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder;
configure(this);
_row.AppendChild(cellBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public IRow Cell(string text)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder;
2026-09-02 16:42:34 +07:00
cellBuilder.Paragraph(p => p.Run(text));
2026-06-05 15:58:03 +07:00
_row.AppendChild(cellBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public IRow Cell(string text, FontProps font)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder;
if (font is not null)
2026-09-02 16:42:34 +07:00
cellBuilder.Paragraph(p => p.Run(text, font));
else cellBuilder.Paragraph(p => p.Run(text));
2026-06-05 15:58:03 +07:00
_row.AppendChild(cellBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public IRow Cell(CellProps cellProps, string text, FontProps font)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder.SetCellProps(cellProps);
if (font is not null)
2026-09-02 16:42:34 +07:00
cellBuilder.Paragraph(p => p.Run(text, font));
else cellBuilder.Paragraph(p => p.Run(text));
2026-06-05 15:58:03 +07:00
_row.AppendChild(cellBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public IRow Cell(CellProps cellProps, string text)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder.SetCellProps(cellProps);
2026-09-02 16:42:34 +07:00
cellBuilder.Paragraph(p => p.Run(text));
2026-06-05 15:58:03 +07:00
_row.AppendChild(cellBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public IRow Cell(CellProps cellProps)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder.SetCellProps(cellProps);
_row.AppendChild(cellBuilder.Build());
return this;
}
// Метод для установки произвольных свойств строки
public IRow SetProperties(Action<TableRowProperties> configure)
{
_row.TableRowProperties ??= new TableRowProperties();
configure(_row.TableRowProperties);
return this;
}
2026-09-02 16:42:34 +07:00
public IRow CellWithPara(Action<IParagraph> configure)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder;
2026-09-02 16:42:34 +07:00
cellBuilder.Paragraph(configure);
2026-06-05 15:58:03 +07:00
_row.AppendChild(cellBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public IRow CellWithPara(CellProps cellProps, Action<IParagraph> configure)
2026-06-05 15:58:03 +07:00
{
var cellBuilder = CellBuilder.SetCellProps(cellProps);
2026-09-02 16:42:34 +07:00
cellBuilder.Paragraph(configure);
2026-06-05 15:58:03 +07:00
_row.AppendChild(cellBuilder.Build());
return this;
}
private TableCell _cell = null!;
private List<Paragraph> _paragraphs = null!;
internal ICell CellBuilder
{
get
{
_cell = new();
_paragraphs = [];
return this;
}
}
TableCell ICell.Build()
{
foreach (var paragraph in _paragraphs)
{
_cell.AppendChild(paragraph);
}
return _cell;
}
// Установка свойств ячейки
public ICell SetCellProps(CellProps props)
{
if (props.TryExtract(out var elements))
{
_cell.TableCellProperties = new TableCellProperties(elements);
}
return this;
}
// Добавление параграфов
2026-09-02 16:42:34 +07:00
public ICell Paragraph(Action<IParagraph> configure)
2026-06-05 15:58:03 +07:00
{
var paraBuilder = ParagraphBuilder;
configure(paraBuilder);
_paragraphs.Add(paraBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public ICell Paragraph(string text, FontProps? font = null)
2026-06-05 15:58:03 +07:00
{
var paraBuilder = ParagraphBuilder;
if (font is not null)
{
2026-09-02 16:42:34 +07:00
paraBuilder.Run(text, font);
2026-06-05 15:58:03 +07:00
}
else
{
2026-09-02 16:42:34 +07:00
paraBuilder.Run(text);
2026-06-05 15:58:03 +07:00
}
_paragraphs.Add(paraBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
public ICell Paragraph(params string[] lines)
2026-06-05 15:58:03 +07:00
{
var paraBuilder = ParagraphBuilder;
if (lines.Length > 0)
{
2026-09-02 16:42:34 +07:00
paraBuilder.Run(lines[0]);
2026-06-05 15:58:03 +07:00
for (int i = 1; i < lines.Length; i++)
{
paraBuilder.Break();
2026-09-02 16:42:34 +07:00
paraBuilder.Run(lines[i]);
2026-06-05 15:58:03 +07:00
}
}
_paragraphs.Add(paraBuilder.Build());
return this;
}
2026-09-02 16:42:34 +07:00
// Метод Formula для ICellBuilder
ICell ICell.Formula(Action<IFormula> configure)
2026-06-05 15:58:03 +07:00
{
var paraBuilder = ParagraphBuilder;
2026-09-02 16:42:34 +07:00
paraBuilder.Formula(configure);
2026-06-05 15:58:03 +07:00
_paragraphs.Add(paraBuilder.Build());
return this;
}
}