ASCU_ALL/PrintPDF/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/TableFormatter.cs

249 lines
9.5 KiB
C#
Raw Normal View History

2020-09-04 12:49:15 +05:00
using System.Diagnostics;
namespace MigraDoc.DocumentObjectModel.Tables
{
/// <summary>
/// Contains methods to simplify table formatting.
/// </summary>
public static class TableFormatter
{
/// <summary>
/// Adds one variable count of rows and columns to the top, right, bottom and left of the table.
/// </summary>
/// <param name="table"></param>
/// <param name="newSurroundingCells"></param>
public static void ExpandTable(Table table, int newSurroundingCells)
{
ExpandTable(table, newSurroundingCells, newSurroundingCells, newSurroundingCells, newSurroundingCells);
}
/// <summary>
/// Adds one variable count of rows and one of columns to the right and the bottom of the table.
/// </summary>
/// <param name="table"></param>
/// <param name="newColsRight"></param>
/// <param name="newRowsBottom"></param>
public static void ExpandTable(Table table, int newColsRight, int newRowsBottom)
{
ExpandTable(table, 0, newColsRight, newRowsBottom, 0);
}
/// <summary>
/// Adds variable counts of rows and columns to the top, right, bottom and of left of the table.
/// </summary>
/// <param name="table"></param>
/// <param name="newRowsTop"></param>
/// <param name="newColsRight"></param>
/// <param name="newRowsBottom"></param>
/// <param name="newColsLeft"></param>
public static void ExpandTable(Table table, int newRowsTop, int newColsRight, int newRowsBottom, int newColsLeft)
{
for (int i = 0; i < newRowsTop; i++)
table.Rows.InsertObject(0, new Row());
for (int i = 0; i < newColsLeft; i++)
{
table.Columns.InsertObject(0, new Column());
foreach (Row row in table.Rows)
row.Cells.InsertObject(0, new Cell());
}
for (int i = 0; i < newRowsBottom; i++)
table.Rows.Add(new Row());
for (int i = 0; i < newColsRight; i++)
table.Columns.Add(new Column());
}
/// <summary>
/// Sets the corner cells of the table to rounded corners.
/// </summary>
/// <param name="table"></param>
public static void SetRoundedCorners(Table table)
{
int rowCount = table.Rows.Count;
int colCount = table.Columns.Count;
if (rowCount < 2 || colCount < 2)
return;
table.Rows[0].Cells[0].RoundedCorner = RoundedCorner.TopLeft;
table.Rows[0].Cells[colCount - 1].RoundedCorner = RoundedCorner.TopRight;
table.Rows[rowCount - 1].Cells[colCount - 1].RoundedCorner = RoundedCorner.BottomRight;
table.Rows[rowCount - 1].Cells[0].RoundedCorner = RoundedCorner.BottomLeft;
}
/// <summary>
/// Sets the width/height of the outer columns/rows to one value.
/// </summary>
/// <param name="table"></param>
/// <param name="width"></param>
public static void SetOuterCellsWidth(Table table, Unit width)
{
SetOuterCellsWidth(table, width, width);
}
/// <summary>
/// Sets each the width of the outer columns and the height of the outer rows to a value.
/// </summary>
/// <param name="table"></param>
/// <param name="width"></param>
/// <param name="height"></param>
public static void SetOuterCellsWidth(Table table, Unit width, Unit height)
{
int rowCount = table.Rows.Count;
int colCount = table.Columns.Count;
if (rowCount < 2 || colCount < 2)
return;
table.Columns[0].Width = width;
table.Columns[colCount - 1].Width = width;
table.Rows[0].Height = height;
table.Rows[0].HeightRule = RowHeightRule.Exactly;
table.Rows[rowCount - 1].Height = height;
table.Rows[rowCount - 1].HeightRule = RowHeightRule.Exactly;
}
/// <summary>
/// Get the Shading of the first "targetRowCount" Rows from the Row below.
/// </summary>
/// <param name="table"></param>
/// <param name="targetRowCount"></param>
public static void CopyNeighbouringRowShadingToTop(Table table, int targetRowCount)
{
if (table.Rows.Count <= targetRowCount)
return;
Row source = table.Rows[targetRowCount];
for (int i = 0; i < targetRowCount; i++)
table.Rows[i].Shading = source.Shading.Clone();
}
/// <summary>
/// Get the Shading of the last "targetRowCount" Rows from the Row above.
/// </summary>
/// <param name="table"></param>
/// <param name="targetRowCount"></param>
public static void CopyNeighbouringRowShadingToBottom(Table table, int targetRowCount)
{
int lastIndex = table.Rows.Count - 1;
if (lastIndex - targetRowCount < 0)
return;
Row source = table.Rows[lastIndex - targetRowCount];
for (int i = 0; i < targetRowCount; i++)
table.Rows[lastIndex - i].Shading = source.Shading.Clone();
}
/// <summary>
/// Removes all inner horizontal Borders between "start" index and the next "count" Rows.
/// </summary>
/// <param name="table"></param>
/// <param name="start"></param>
/// <param name="count"></param>
public static void RemoveInnerHorizontalBorders(Table table, int start, int count)
{
int end = start + count;
for (int i = start; i < end - 1; i++)
{
if (i + 1 >= table.Rows.Count)
break;
table.Rows[i].Borders.Bottom.Visible = false;
table.Rows[i + 1].Borders.Top.Visible = false;
}
}
/// <summary>
/// Removes all inner vertical Borders between "start" index and the next "count" Columns.
/// </summary>
/// <param name="table"></param>
/// <param name="start"></param>
/// <param name="count"></param>
public static void RemoveInnerVerticalBorders(Table table, int start, int count)
{
int end = start + count;
for (int i = start; i < end - 1; i++)
{
if (i + 1 >= table.Columns.Count)
break;
table.Columns[i].Borders.Right.Visible = false;
table.Columns[i + 1].Borders.Left.Visible = false;
}
}
/// <summary>
/// Inserts a magic glue column to avoid PageBreaks at the first "rowCountTop" and the last "rowCountBottom" of a Table.
/// </summary>
/// <param name="table"></param>
/// <param name="insertAtIndex"></param>
/// <param name="rowCountTop">For example 3 for rounded corners Row, Header Row and first content Row.</param>
/// <param name="rowCountBottom">For example 2 for last content Row and rounded corners Row.</param>
public static void InsertGlueColumn(Table table, int insertAtIndex, int rowCountTop, int rowCountBottom)
{
if (table.Columns.Count == 0)
return;
int glueColumnIndex = insertAtIndex + 1;
Unit glueColumnWidth = Unit.FromPoint(0.1);
Column glueColumn = new Column();
glueColumn.Width = glueColumnWidth;
if (table.Columns[insertAtIndex].Width > glueColumnWidth)
table.Columns[insertAtIndex].Width -= glueColumnWidth;
table.Columns.InsertObject(glueColumnIndex, glueColumn);
foreach (Row row in table.Rows)
{
if (row.Cells.Count > glueColumnIndex)
row.Cells.InsertObject(glueColumnIndex, new Cell());
}
int mergeTop = rowCountTop - 1;
if (mergeTop < table.Rows.Count)
table.Rows[0].Cells[glueColumnIndex].MergeDown = mergeTop;
int mergeBottom = rowCountBottom - 1;
if (table.Rows.Count - 1 - mergeBottom >= 0)
table.Rows[table.Rows.Count - 1 - mergeBottom].Cells[glueColumnIndex].MergeDown = mergeBottom;
}
/// <summary>
/// Surrounds "count" Elements beginning with index "start" with a one-Column Table of the specified width, where each row contains one of the paragraphs.
/// </summary>
/// <param name="section"></param>
/// <param name="start"></param>
/// <param name="count"></param>
/// <param name="columnWidth"></param>
public static Table SurroundContentWithTable(Section section, int start, int count, Unit columnWidth)
{
Table table = new Table();
table.Columns.AddColumn();
table.Borders.Width = 0;
table.Columns[0].Width = columnWidth;
while (count-- > 0)
{
Row row = table.AddRow();
row.Cells.Add(new Cell());
Paragraph paragraph = section.Elements[start].Clone() as Paragraph;
if (paragraph != null)
{
row.Cells[0].Add(paragraph);
section.Elements.RemoveObjectAt(start);
}
else
Debug.Assert(false);
}
section.Elements.InsertObject(start, table);
return table;
}
}
}