Gabungkan Sel Tabel

Terkadang baris tertentu dalam tabel memerlukan judul atau blok teks besar yang memenuhi seluruh lebar tabel. Untuk desain tabel yang benar, pengguna dapat menggabungkan beberapa sel tabel menjadi satu. Aspose.Words mendukung sel gabungan saat bekerja dengan semua format masukan, termasuk mengimpor konten HTML.

Cara Menggabungkan Sel Tabel

Di Aspose.Words, sel yang digabungkan diwakili oleh properti kelas CellFormat berikut:

  • HorizontalMerge yang menjelaskan jika sel merupakan bagian dari gabungan sel horizontal
  • VerticalMerge yang menjelaskan jika sel merupakan bagian dari gabungan sel vertikal

Nilai properti ini menentukan perilaku penggabungan sel:

Periksa apakah Sel Digabung

Untuk memeriksa apakah sel merupakan bagian dari rangkaian sel yang digabungkan, kita cukup memeriksa properti HorizontalMerge dan VerticalMerge.

Contoh kode berikut menunjukkan cara mencetak tipe gabungan sel horizontal dan vertikal:

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

Gabungkan Sel Tabel Saat Menggunakan DocumentBuilder

Untuk menggabungkan sel dalam tabel yang dibuat dengan DocumentBuilder, Anda perlu mengatur jenis penggabungan yang sesuai untuk setiap sel yang diharapkan akan digabungkan – pertama CellMerge.First dan kemudian CellMerge.Previous.

Selain itu, Anda harus ingat untuk menghapus pengaturan penggabungan untuk sel-sel yang tidak memerlukan penggabungan – ini dapat dilakukan dengan mengatur sel pertama yang tidak digabungkan ke CellMerge.None. Jika ini tidak dilakukan, semua sel dalam tabel akan digabungkan.

Contoh kode berikut menunjukkan cara membuat tabel dengan dua baris dimana sel-sel di baris pertama digabungkan secara horizontal:

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

Contoh kode berikut menunjukkan cara membuat tabel dua kolom dengan sel-sel di kolom pertama digabungkan secara vertikal:

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

Gabungkan Sel Tabel dalam Kasus Lain

Dalam situasi lain di mana DocumentBuilder tidak digunakan, misalnya pada tabel yang sudah ada, menggabungkan sel dengan cara sebelumnya mungkin tidak semudah itu. Sebagai gantinya, kita bisa menggabungkan operasi dasar yang terlibat dalam penerapan properti gabungan ke sel dalam metode yang membuat tugas lebih mudah. Metode ini mirip dengan metode otomatisasi Penggabungan, yang dipanggil untuk menggabungkan rentang sel dalam sebuah tabel.

Kode di bawah ini akan menggabungkan sel-sel tabel dalam rentang yang ditentukan, dimulai dari sel tertentu dan berakhir di sel akhir. Dalam hal ini, rentang dapat mencakup beberapa baris atau kolom:

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

Contoh kode berikut menunjukkan cara menggabungkan rentang sel antara dua sel tertentu:

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

Tergantung pada versi .NET Framework yang Anda gunakan, Anda mungkin ingin menyempurnakan metode ini dengan mengubahnya menjadi metode ekstensi. Dalam hal ini, Anda bisa memanggil metode ini secara langsung pada sel untuk menggabungkan rentang sel, seperti cell1.Merge(cell2).

Sel Gabungan Vertikal dan Horizontal dalam Tabel HTML

Seperti yang telah kami katakan di artikel sebelumnya, tabel di Microsoft Word adalah sekumpulan baris independen. Setiap baris memiliki sekumpulan sel yang tidak bergantung pada sel baris lainnya. Jadi, dalam tabel Microsoft Word tidak ada objek seperti “kolom”, dan “kolom pertama” adalah sesuatu seperti “kumpulan sel pertama dari setiap baris dalam tabel”. Hal ini memungkinkan pengguna untuk memiliki tabel yang, misalnya, baris pertama terdiri dari dua sel – 2cm dan 1cm, dan baris ke-2 terdiri dari dua sel berbeda – lebar 1cm dan 2cm. Dan Aspose.Words mendukung konsep tabel ini.

Tabel dalam HTML pada dasarnya memiliki struktur yang berbeda: setiap baris memiliki jumlah sel yang sama dan (penting untuk tugas ini) setiap sel memiliki lebar kolom yang sesuai, sama untuk semua sel dalam satu kolom. Jadi jika HorizontalMerge dan VerticalMerge mengembalikan nilai yang salah, gunakan contoh kode berikut:

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

Konversikan ke Sel yang Digabung Secara Horizontal

Terkadang tidak mungkin mendeteksi sel mana yang digabungkan karena beberapa versi Microsoft Word yang lebih baru tidak lagi menggunakan tanda penggabungan saat sel digabungkan secara horizontal. Namun untuk situasi di mana sel digabungkan ke dalam sel secara horizontal berdasarkan lebarnya menggunakan tanda gabungan, Aspose.Words menyediakan metode ConvertToHorizontallyMergedCells untuk mengonversi sel. Metode ini hanya mengubah tabel dan menambahkan sel baru sesuai kebutuhan.

Contoh kode berikut menunjukkan cara kerja metode di atas:

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