Об'ємні клітини таблиці

Іноді деякі ряди в таблиці вимагають заголовка або великі блоки тексту, які займають повну ширину таблиці. Для належного оформлення таблиці користувач може об’єднати кілька клітин таблиці в одну. Aspose.Words підтримує об’єднані клітинки при роботі з усіма форматами введення, включаючи імпортування контенту HTML.

Як захопити настільні клітини

У Aspose.Words, Об’єднані клітинки представлені такими властивостями CellFormat клас:

  • до HorizontalMerge що описує, якщо клітина є частиною горизонтального зливу клітин
  • до VerticalMerge що описує, якщо клітина є частиною вертикальної зливи клітин

Значення цих властивостей визначають концентрацію поведінки клітин:

  • до Перша клітинка в послідовності об’єднаних клітин буде мати CellMerge.First
  • до Будь-який згодом об’єднані клітинки будуть мати CellMerge.Previous
  • Клітка, яка не зливається, буде мати CellMerge.None

Перевірте, чи працює клітина

Щоб перевірити, чи є клітинка частиною послідовності з’єднаних клітин, ми просто перевіряємо HorizontalMerge і VerticalMerge властивості.

Приклад наступного коду показує, як друкувати горизонтальний і вертикальний тип зливу клітин:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document doc = new Document(MyDir + "Table with merged cells.docx");
Table table = (Table) doc.GetChild(NodeType.Table, 0, true);
foreach (Row row in table.Rows)
{
foreach (Cell cell in row.Cells)
{
Console.WriteLine(PrintCellMergeType(cell));
}
}

Об’єднайте клітинки таблиці під час використання DocumentBuilder

Щоб об’єднати клітинки в таблиці, створеному з DocumentBuilder, потрібно встановити відповідний тип злиття для кожної комірки, де очікується концентрація – перший CellMerge.First а потім CellMerge.Previousй

Крім того, ви повинні пам’ятати, щоб очистити налаштування об’єднання для тих клітин, де не потрібно об’єднати - це може бути зроблено, встановивши перший не мерге клітинки, щоб CellMerge.Noneй Якщо це не зроблено, всі клітини в таблиці будуть об’єднані.

Приклад коду показує, як створити таблицю з двома рядами, де клітини в першому ряду об’єднуються горизонтально:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.First;
builder.Write("Text in merged cells.");
builder.InsertCell();
// This cell is merged to the previous and should be empty.
builder.CellFormat.HorizontalMerge = CellMerge.Previous;
builder.EndRow();
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.Write("Text in one cell.");
builder.InsertCell();
builder.Write("Text in another cell.");
builder.EndRow();
builder.EndTable();
doc.Save(ArtifactsDir + "WorkingWithTables.HorizontalMerge.docx");

Приклад наступного коду показує, як створити двосторонній стіл, де клітинки в першому стовпчику вертикально з’єднуються:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.First;
builder.Write("Text in merged cells.");
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.None;
builder.Write("Text in one cell");
builder.EndRow();
builder.InsertCell();
// This cell is vertically merged to the cell above and should be empty.
builder.CellFormat.VerticalMerge = CellMerge.Previous;
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.None;
builder.Write("Text in another cell");
builder.EndRow();
builder.EndTable();
doc.Save(ArtifactsDir + "WorkingWithTables.VerticalMerge.docx");

Об’ємні клітини таблиці в інших випадках

В інших ситуаціях, де DocumentBuilder не використовується, наприклад, в існуючому столі, злиття клітин в попередньому вигляді може бути не так просто. Замість цього ми можемо обгорнути основні операції, які беруть участь у застосуванні об’єднувальних властивостей до клітин в методі, що робить завдання набагато простіше. Цей метод схожий на метод автоматизації Merge, який називається об’єднання діапазону клітин в таблиці.

Введіть номер мобільного, який Ви вказали при укладаннi договору з банком - для ідентифікації. У цьому випадку діапазон може пропускати декілька рядків або стовпців:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
internal void MergeCells(Cell startCell, Cell endCell)
{
Table parentTable = startCell.ParentRow.ParentTable;
// Find the row and cell indices for the start and end cell.
Point startCellPos = new Point(startCell.ParentRow.IndexOf(startCell),
parentTable.IndexOf(startCell.ParentRow));
Point endCellPos = new Point(endCell.ParentRow.IndexOf(endCell), parentTable.IndexOf(endCell.ParentRow));
// Create a range of cells to be merged based on these indices.
// Inverse each index if the end cell is before the start cell.
Rectangle mergeRange = new Rectangle(Math.Min(startCellPos.X, endCellPos.X),
Math.Min(startCellPos.Y, endCellPos.Y),
Math.Abs(endCellPos.X - startCellPos.X) + 1, Math.Abs(endCellPos.Y - startCellPos.Y) + 1);
foreach (Row row in parentTable.Rows)
{
foreach (Cell cell in row.Cells)
{
Point currentPos = new Point(row.IndexOf(cell), parentTable.IndexOf(row));
// Check if the current cell is inside our merge range, then merge it.
if (mergeRange.Contains(currentPos))
{
cell.CellFormat.HorizontalMerge = currentPos.X == mergeRange.X ? CellMerge.First : CellMerge.Previous;
cell.CellFormat.VerticalMerge = currentPos.Y == mergeRange.Y ? CellMerge.First : CellMerge.Previous;
}
}
}
}
view raw merge-cells.cs hosted with ❤ by GitHub

Приклад наступного коду показує, як об’єднати діапазон клітин між двома вказаними клітинами:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document doc = new Document(MyDir + "Table with merged cells.docx");
Table table = doc.FirstSection.Body.Tables[0];
// We want to merge the range of cells found inbetween these two cells.
Cell cellStartRange = table.Rows[0].Cells[0];
Cell cellEndRange = table.Rows[1].Cells[1];
// Merge all the cells between the two specified cells into one.
MergeCells(cellStartRange, cellEndRange);
doc.Save(ArtifactsDir + "WorkingWithTables.MergeCellRange.docx");

Залежно від версії .NET Framework Ви використовуєте, ви можете переглянути цей метод, перетворюючи його в метод розширення. У цьому випадку ви можете викликати цей метод безпосередньо на клітинку, щоб об’єднати діапазон клітин, таких як cell1.Merge(cell2)й

Вертикальні та горизонтальні з’єднувальні клітини в HTML таблиці

Як ми говорили в попередніх статтях, таблиці в Microsoft Word – набір незалежних рядків. Кожен ряд має набір клітин, які не залежать від клітин інших рядків. Так, в Microsoft Word У таблиці немає такого об’єкта, як “холодний”, а “1й стовпчик” – це те, що “комплект 1 клітин кожного ряду в таблиці”. Це дозволяє користувачам мати таблицю, в якому, наприклад, 1-й ряд складається з двох клітин – 2см і 1см, а 2-й ряд складається з двох різних клітин – 1см і шириною 2см. І Aspose.Words підтримує цю концепцію таблиць.

Стіл в HTML має істотно різну структуру: кожен ряд має однакову кількість клітин і (це важливо для завдання) кожна клітинка має ширину відповідного стовпчика, тим самим для всіх клітин в одному стовпчику. Так, якщо HorizontalMerge і VerticalMerge Поверніть неправильне значення, використовуйте наступний приклад коду:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document doc = new Document(MyDir + "Table with merged cells.docx");
SpanVisitor visitor = new SpanVisitor(doc);
doc.Accept(visitor);
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
/// <summary>
/// Helper class that contains collection of rowinfo for each row.
/// </summary>
public class TableInfo
{
public List<RowInfo> Rows { get; } = new List<RowInfo>();
}
/// <summary>
/// Helper class that contains collection of cellinfo for each cell.
/// </summary>
public class RowInfo
{
public List<CellInfo> Cells { get; } = new List<CellInfo>();
}
/// <summary>
/// Helper class that contains info about cell. currently here is only colspan and rowspan.
/// </summary>
public class CellInfo
{
public CellInfo(int colSpan, int rowSpan)
{
ColSpan = colSpan;
RowSpan = rowSpan;
}
public int ColSpan { get; }
public int RowSpan { get; }
}
public class SpanVisitor : DocumentVisitor
{
/// <summary>
/// Creates new SpanVisitor instance.
/// </summary>
/// <param name="doc">
/// Is document which we should parse.
/// </param>
public SpanVisitor(Document doc)
{
mWordTables = doc.GetChildNodes(NodeType.Table, true);
// We will parse HTML to determine the rowspan and colspan of each cell.
MemoryStream htmlStream = new MemoryStream();
Aspose.Words.Saving.HtmlSaveOptions options = new Aspose.Words.Saving.HtmlSaveOptions
{
ImagesFolder = Path.GetTempPath()
};
doc.Save(htmlStream, options);
// Load HTML into the XML document.
XmlDocument xmlDoc = new XmlDocument();
htmlStream.Position = 0;
xmlDoc.Load(htmlStream);
// Get collection of tables in the HTML document.
XmlNodeList tables = xmlDoc.DocumentElement.GetElementsByTagName("table");
foreach (XmlNode table in tables)
{
TableInfo tableInf = new TableInfo();
// Get collection of rows in the table.
XmlNodeList rows = table.SelectNodes("tr");
foreach (XmlNode row in rows)
{
RowInfo rowInf = new RowInfo();
// Get collection of cells.
XmlNodeList cells = row.SelectNodes("td");
foreach (XmlNode cell in cells)
{
// Determine row span and colspan of the current cell.
XmlAttribute colSpanAttr = cell.Attributes["colspan"];
XmlAttribute rowSpanAttr = cell.Attributes["rowspan"];
int colSpan = colSpanAttr == null ? 0 : int.Parse(colSpanAttr.Value);
int rowSpan = rowSpanAttr == null ? 0 : int.Parse(rowSpanAttr.Value);
CellInfo cellInf = new CellInfo(colSpan, rowSpan);
rowInf.Cells.Add(cellInf);
}
tableInf.Rows.Add(rowInf);
}
mTables.Add(tableInf);
}
}
public override VisitorAction VisitCellStart(Cell cell)
{
int tabIdx = mWordTables.IndexOf(cell.ParentRow.ParentTable);
int rowIdx = cell.ParentRow.ParentTable.IndexOf(cell.ParentRow);
int cellIdx = cell.ParentRow.IndexOf(cell);
int colSpan = 0;
int rowSpan = 0;
if (tabIdx < mTables.Count &&
rowIdx < mTables[tabIdx].Rows.Count &&
cellIdx < mTables[tabIdx].Rows[rowIdx].Cells.Count)
{
colSpan = mTables[tabIdx].Rows[rowIdx].Cells[cellIdx].ColSpan;
rowSpan = mTables[tabIdx].Rows[rowIdx].Cells[cellIdx].RowSpan;
}
Console.WriteLine("{0}.{1}.{2} colspan={3}\t rowspan={4}", tabIdx, rowIdx, cellIdx, colSpan, rowSpan);
return VisitorAction.Continue;
}
private readonly List<TableInfo> mTables = new List<TableInfo>();
private readonly NodeCollection mWordTables;
}

Перетворення в горизонтально Об’єднані клітинки

Іноді не можна виявити, які клітинки об’єднані через деякі нові версії Microsoft Word більше не використовуйте прапори злиття, коли клітини об’єднуються горизонтально. Але для ситуацій, де клітини зливаються в клітинку горизонтально за їх шириною за допомогою прапорів злиття, Aspose.Words забезпечує ConvertToHorizontallyMergedCells спосіб перетворення клітин. Цей метод просто перетворює таблицю і додає нові клітинки в міру необхідності.

Приклад коду показує вище метод в роботі:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document doc = new Document(MyDir + "Table with merged cells.docx");
Table table = doc.FirstSection.Body.Tables[0];
// Now merged cells have appropriate merge flags.
table.ConvertToHorizontallyMergedCells();