328 lines
8.9 KiB
C#
328 lines
8.9 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|