Tabelcellen samenvoegen

Soms vereisen bepaalde rijen in een tabel een kop of grote blokken tekst die de volledige breedte van de tabel innemen. Voor het juiste ontwerp van de tabel, kan de gebruiker meerdere tabelcellen in één samenvoegen. Aspose.Words ondersteunt samengevoegde cellen bij het werken met alle invoerformaten, waaronder het importeren van HTML-inhoud.

Hoe tabelcellen samenvoegen

In Aspose.Words, samengevoegde cellen worden vertegenwoordigd door de volgende eigenschappen van de CellFormat klasse:

  • HorizontalMerge die beschrijft of de cel deel uitmaakt van een horizontale samenvoeging van cellen
  • VerticalMerge die beschrijft of de cel deel uitmaakt van een verticale samenvoeging van cellen

De waarden van deze eigenschappen bepalen het samenvoeggedrag van cellen:

Controleer of de cel is samengevoegd

Om te controleren of een cel deel uitmaakt van een opeenvolging van samengevoegde cellen, controleren we gewoon de HorizontalMerge en VerticalMerge eigenschappen.

Het volgende voorbeeld van code laat zien hoe het horizontale en verticale cel merge type af te drukken:

// 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));
}
}

Tabelcellen samenvoegen bij gebruik van DocumentBuilder

Het samenvoegen van cellen in een tabel gemaakt met de DocumentBuilder, je moet het juiste mergetype instellen voor elke cel waar de merge wordt verwacht CellMerge.First en dan CellMerge.Previous.

Ook moet je onthouden om de merge instelling voor die cellen waar geen merge nodig is te wissen CellMerge.None. Als dit niet gebeurt, worden alle cellen in de tabel samengevoegd.

Het volgende voorbeeld van code laat zien hoe je een tabel maakt met twee rijen waar de cellen in de eerste rij horizontaal worden samengevoegd:

// 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");

Het volgende voorbeeld van code laat zien hoe je een tabel met twee kolommen aanmaakt waar de cellen in de eerste kolom verticaal zijn samengevoegd:

// 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");

Tabelcellen samenvoegen in andere gevallen

In andere situaties waar de DocumentBuilder wordt niet gebruikt, zoals in een bestaande tabel, het samenvoegen van cellen op de vorige manier kan niet zo gemakkelijk zijn. In plaats daarvan kunnen we de basisbewerkingen die betrokken zijn bij het toepassen van merge eigenschappen op cellen in een methode die de taak veel gemakkelijker maakt. Deze methode is vergelijkbaar met de Merge automatiseringsmethode, die wordt opgeroepen om een reeks cellen in een tabel samen te voegen.

De onderstaande code zal de tabelcellen samenvoegen in het opgegeven bereik, beginnend bij de gegeven cel en eindigend bij de eindcel. In dit geval kan het bereik meerdere rijen of kolommen omvatten:

// 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

Het volgende voorbeeld van code laat zien hoe je een reeks cellen tussen twee gespecificeerde cellen kunt samenvoegen:

// 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");

Afhankelijk van de versie van de .NET Framework u gebruikt, kunt u deze methode te verfijnen door het om te zetten in een extensiemethode. In dit geval kunt u deze methode direct op een cel te mergen een reeks cellen, zoals cell1.Merge(cell2).

Verticale en horizontale samengevoegde cellen in HTML-tabel

Zoals gezegd in vorige artikelen, een tabel in Microsoft Word is een reeks onafhankelijke rijen. Elke rij heeft een reeks cellen die onafhankelijk zijn van de cellen van andere rijen. In de Microsoft Word tabel er is geen object als een. .. .. .. 1e kolom. .. . de set van de 1e cellen van elke rij in de tabel. Hierdoor kunnen gebruikers een tabel hebben waarin bijvoorbeeld de 1e rij bestaat uit twee cellen 2cm en 1cm, en de 2e rij bestaat uit twee verschillende cellen 1cm en 2cm breed. En Aspose.Words steunt dit concept van tabellen.

Een tabel in HTML heeft een wezenlijk andere structuur: elke rij heeft hetzelfde aantal cellen en (het is belangrijk voor de taak) elke cel heeft de breedte van de overeenkomstige kolom, hetzelfde voor alle cellen in één kolom. Dus als HorizontalMerge en VerticalMerge retour een onjuiste waarde, gebruik het volgende code voorbeeld:

// 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;
}

Omzetten naar horizontaal Samengevoegde cellen

Soms is het niet mogelijk om te detecteren welke cellen worden samengevoegd omdat sommige nieuwere versies van Microsoft Word de mergevlaggen niet meer gebruiken wanneer cellen horizontaal worden samengevoegd. Maar voor situaties waarin cellen worden samengevoegd in een cel horizontaal door hun breedte met behulp van merge vlaggen, Aspose.Words levert de ConvertToHorizontallyMergedCells methode om cellen te converteren. Deze methode transformeert eenvoudigweg de tabel en voegt zo nodig nieuwe cellen toe.

Het volgende voorbeeld van code toont de bovenstaande methode in werking:

// 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();