Files
QWERTYkez.OpenXmlProcessors/QWERTYkez.WordProcessor/Builders/TableBuilder.cs
2026-06-05 15:58:03 +07:00

328 lines
8.9 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.WordProcessor.Builders;
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
public ITable AddRow(Action<IRow> configure)
{
var IRowBuilder = RowBuilder;
configure(this);
_table.AppendChild(IRowBuilder.Build());
return this;
}
public ITable AddRow(double height, Action<IRow> configure)
{
var IRowBuilder = RowBuilder.SetHeight(height);
configure(this);
_table.AppendChild(IRowBuilder.Build());
return this;
}
// Быстрые методы для добавления строк с ячейками
public ITable AddRowWithCells(params string[] cellTexts)
{
AddRow(row =>
{
foreach (var text in cellTexts)
{
row.AddCell(text);
}
});
return this;
}
public ITable AddRowWithCells(FontProps font, params string[] cellTexts)
{
AddRow(row =>
{
foreach (var text in cellTexts)
{
row.AddCell(text, font);
}
});
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;
}
// Добавление ячеек
public IRow AddCell(Action<ICell> configure)
{
var cellBuilder = CellBuilder;
configure(this);
_row.AppendChild(cellBuilder.Build());
return this;
}
public IRow AddCell(string text)
{
var cellBuilder = CellBuilder;
cellBuilder.AddParagraph(p => p.AddRun(text));
_row.AppendChild(cellBuilder.Build());
return this;
}
public IRow AddCell(string text, FontProps font)
{
var cellBuilder = CellBuilder;
if (font is not null)
cellBuilder.AddParagraph(p => p.AddRun(text, font));
else cellBuilder.AddParagraph(p => p.AddRun(text));
_row.AppendChild(cellBuilder.Build());
return this;
}
public IRow AddCell(CellProps cellProps, string text, FontProps font)
{
var cellBuilder = CellBuilder.SetCellProps(cellProps);
if (font is not null)
cellBuilder.AddParagraph(p => p.AddRun(text, font));
else cellBuilder.AddParagraph(p => p.AddRun(text));
_row.AppendChild(cellBuilder.Build());
return this;
}
public IRow AddCell(CellProps cellProps, string text)
{
var cellBuilder = CellBuilder.SetCellProps(cellProps);
cellBuilder.AddParagraph(p => p.AddRun(text));
_row.AppendChild(cellBuilder.Build());
return this;
}
public IRow AddCell(CellProps cellProps)
{
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;
}
public IRow AddCellWithPara(Action<IParagraph> configure)
{
var cellBuilder = CellBuilder;
cellBuilder.AddParagraph(configure);
_row.AppendChild(cellBuilder.Build());
return this;
}
public IRow AddCellWithPara(CellProps cellProps, Action<IParagraph> configure)
{
var cellBuilder = CellBuilder.SetCellProps(cellProps);
cellBuilder.AddParagraph(configure);
_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;
}
// Добавление параграфов
public ICell AddParagraph(Action<IParagraph> configure)
{
var paraBuilder = ParagraphBuilder;
configure(paraBuilder);
_paragraphs.Add(paraBuilder.Build());
return this;
}
public ICell AddParagraph(string text, FontProps? font = null)
{
var paraBuilder = ParagraphBuilder;
if (font is not null)
{
paraBuilder.AddRun(text, font);
}
else
{
paraBuilder.AddRun(text);
}
_paragraphs.Add(paraBuilder.Build());
return this;
}
public ICell AddParagraph(params string[] lines)
{
var paraBuilder = ParagraphBuilder;
if (lines.Length > 0)
{
paraBuilder.AddRun(lines[0]);
for (int i = 1; i < lines.Length; i++)
{
paraBuilder.Break();
paraBuilder.AddRun(lines[i]);
}
}
_paragraphs.Add(paraBuilder.Build());
return this;
}
// Метод AddFormula для ICellBuilder
ICell ICell.AddFormula(Action<IFormula> configure)
{
var paraBuilder = ParagraphBuilder;
paraBuilder.AddFormula(configure);
_paragraphs.Add(paraBuilder.Build());
return this;
}
}