Gabungkan Sel Tabel
Terkadang baris tertentu dalam tabel memerlukan judul atau blok teks besar yang menempati seluruh lebar tabel. Untuk desain tabel yang tepat, pengguna dapat menggabungkan beberapa sel tabel menjadi satu. Aspose.Words mendukung sel gabungan saat bekerja dengan semua format input, termasuk mengimpor konten HTML.
Cara Menggabungkan Sel Tabel
Dalam Aspose.Words, sel yang digabungkan diwakili oleh properti berikut dari kelas CellFormat:
- HorizontalMerge yang menjelaskan apakah sel tersebut merupakan bagian dari penggabungan sel secara horizontal
- VerticalMerge yang menjelaskan jika sel merupakan bagian dari penggabungan vertikal sel
Nilai dari properti ini menentukan perilaku penggabungan sel:
- Sel pertama dalam urutan sel yang digabungkan akan memiliki CellMerge.First
- Setiap sel yang digabungkan selanjutnya akan memiliki CellMerge.Previous
- Sel yang tidak digabungkan akan memiliki CellMerge.None
Memeriksa apakah Sel Digabungkan
Untuk memeriksa apakah sel merupakan bagian dari urutan sel yang digabungkan, kita cukup memeriksa properti HorizontalMerge dan VerticalMerge.
Contoh kode berikut menunjukkan cara mencetak tipe penggabungan sel horizontal dan vertikal:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Table with merged cells.docx"); | |
Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); | |
for (Row row : (Iterable<Row>) table.getRows()) | |
{ | |
for (Cell cell : (Iterable<Cell>) row.getCells()) | |
{ | |
System.out.println(printCellMergeType(cell)); | |
} | |
} |
Gabungkan sel Tabel saat menggunakan DocumentBuilder
Untuk menggabungkan sel dalam tabel yang dibuat dengan DocumentBuilder, Anda perlu menyetel jenis penggabungan yang sesuai untuk setiap sel tempat penggabungan diharapkan-pertama CellMerge.First lalu CellMerge.Previous.
Selain itu, Anda harus ingat untuk menghapus pengaturan penggabungan untuk sel-sel yang tidak memerlukan penggabungan – ini dapat dilakukan dengan menyetel sel non-penggabungan pertama ke CellMerge.None. Jika ini tidak dilakukan, semua sel dalam tabel akan digabungkan.
Contoh kode berikut menunjukkan cara membuat tabel dengan dua baris di mana 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-Java.git. | |
Document doc = new Document(); | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
builder.insertCell(); | |
builder.getCellFormat().setHorizontalMerge(CellMerge.FIRST); | |
builder.write("Text in merged cells."); | |
builder.insertCell(); | |
// This cell is merged to the previous and should be empty. | |
builder.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS); | |
builder.endRow(); | |
builder.insertCell(); | |
builder.getCellFormat().setHorizontalMerge(CellMerge.NONE); | |
builder.write("Text in one cell."); | |
builder.insertCell(); | |
builder.write("Text in another cell."); | |
builder.endRow(); | |
builder.endTable(); | |
doc.save(getArtifactsDir() + "WorkingWithTables.HorizontalMerge.docx"); |
Contoh kode berikut menunjukkan cara membuat tabel dua kolom di mana 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-Java.git. | |
Document doc = new Document(); | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
builder.insertCell(); | |
builder.getCellFormat().setVerticalMerge(CellMerge.FIRST); | |
builder.write("Text in merged cells."); | |
builder.insertCell(); | |
builder.getCellFormat().setVerticalMerge(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.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS); | |
builder.insertCell(); | |
builder.getCellFormat().setVerticalMerge(CellMerge.NONE); | |
builder.write("Text in another cell"); | |
builder.endRow(); | |
builder.endTable(); | |
doc.save(getArtifactsDir() + "WorkingWithTables.VerticalMerge.docx"); |
Gabungkan Sel Tabel dalam Kasus Lain
Dalam situasi lain di mana DocumentBuilder tidak digunakan, seperti di tabel yang ada, menggabungkan sel dengan cara sebelumnya mungkin tidak semudah itu. Sebagai gantinya, kita dapat membungkus operasi dasar yang terlibat dalam menerapkan properti penggabungan ke sel dalam metode yang membuat tugas menjadi 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 tabel dalam rentang yang ditentukan, mulai dari sel yang diberikan dan berakhir di sel akhir. Dalam hal ini, rentang dapat menjangkau beberapa baris atau kolom:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
void mergeCells(Cell startCell, Cell endCell) | |
{ | |
Table parentTable = startCell.getParentRow().getParentTable(); | |
// Find the row and cell indices for the start and end cell. | |
Point startCellPos = new Point(startCell.getParentRow().indexOf(startCell), | |
parentTable.indexOf(startCell.getParentRow())); | |
Point endCellPos = new Point(endCell.getParentRow().indexOf(endCell), parentTable.indexOf(endCell.getParentRow())); | |
// 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.y), | |
Math.min(startCellPos.y, endCellPos.y), | |
Math.abs(endCellPos.x - startCellPos.x) + 1, Math.abs(endCellPos.y - startCellPos.y) + 1); | |
for (Row row : parentTable.getRows()) | |
{ | |
for (Cell cell : row.getCells()) | |
{ | |
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.getCellFormat().setHorizontalMerge(currentPos.x == mergeRange.getX() ? CellMerge.FIRST : CellMerge.PREVIOUS); | |
cell.getCellFormat().setVerticalMerge(currentPos.y == mergeRange.getY() ? CellMerge.FIRST : CellMerge.PREVIOUS); | |
} | |
} | |
} | |
} |
Contoh kode berikut menunjukkan cara menggabungkan rentang sel di antara dua sel yang ditentukan:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Table with merged cells.docx"); | |
Table table = doc.getFirstSection().getBody().getTables().get(0); | |
// We want to merge the range of cells found inbetween these two cells. | |
Cell cellStartRange = table.getRows().get(0).getCells().get(0); | |
Cell cellEndRange = table.getRows().get(1).getCells().get(1); | |
// Merge all the cells between the two specified cells into one. | |
mergeCells(cellStartRange, cellEndRange); | |
doc.save(getArtifactsDir() + "WorkingWithTables.MergeCellRange.docx"); |
Sel Gabungan Vertikal dan Horizontal dalam Tabel HTML
Seperti yang telah kami katakan di artikel sebelumnya, tabel dalam 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 ke-1” adalah sesuatu seperti “himpunan sel ke-1 dari setiap baris dalam tabel”. Ini memungkinkan pengguna untuk memiliki tabel di mana, misalnya, baris ke-1 terdiri dari dua sel-2cm dan 1cm, dan baris ke-2 terdiri dari dua sel yang 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 tersebut) 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-Java.git. | |
Document doc = new Document(getMyDir() + "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-Java.git. | |
/// <summary> | |
/// Helper class that contains collection of rowinfo for each row. | |
/// </summary> | |
public static class TableInfo | |
{ | |
public ArrayList<RowInfo> getRows() { return mRows; } | |
private ArrayList<RowInfo> mRows = new ArrayList<>(); | |
} | |
/// <summary> | |
/// Helper class that contains collection of cellinfo for each cell. | |
/// </summary> | |
public static class RowInfo | |
{ | |
public ArrayList<CellInfo> getCells() { return mCells; }; | |
private ArrayList<CellInfo> mCells = new ArrayList<>(); | |
} | |
/// <summary> | |
/// Helper class that contains info about cell. currently here is only colspan and rowspan. | |
/// </summary> | |
public static class CellInfo | |
{ | |
public CellInfo(int colSpan, int rowSpan) | |
{ | |
mColSpan = colSpan; | |
mRowSpan = rowSpan; | |
} | |
public int getColSpan() { return mColSpan; }; | |
private int mColSpan; | |
public int getRowSpan() { return mRowSpan; }; | |
private int mRowSpan; | |
} | |
public static class SpanVisitor extends DocumentVisitor | |
{ | |
/// <summary> | |
/// Creates new SpanVisitor instance. | |
/// </summary> | |
/// <param name="doc"> | |
/// Is document which we should parse. | |
/// </param> | |
public SpanVisitor(Document doc) throws Exception { | |
mWordTables = doc.getChildNodes(NodeType.TABLE, true); | |
// We will parse HTML to determine the rowspan and colspan of each cell. | |
ByteArrayOutputStream htmlStream = new ByteArrayOutputStream(); | |
HtmlSaveOptions options = new HtmlSaveOptions(); | |
{ | |
options.setImagesFolder(System.getProperty("java.io.tmpdir")); | |
} | |
doc.save(htmlStream, options); | |
// Load HTML into the XML document. | |
org.jsoup.nodes.Document document = Jsoup.parse(htmlStream.toString()); | |
// Get collection of tables in the HTML document. | |
Elements tables = document.getElementsByTag("table"); | |
for (Element table : tables) { | |
TableInfo tableInf = new TableInfo(); | |
// Get collection of rows in the table. | |
Elements rows = table.getElementsByTag("tr"); | |
for (Element row : rows) { | |
RowInfo rowInf = new RowInfo(); | |
// Get collection of cells. | |
Elements cells = row.getElementsByTag("td"); | |
for (Element cell : cells) { | |
// Determine row span and colspan of the current cell. | |
String colSpanAttr = cell.attributes().get("colspan"); | |
String rowSpanAttr = cell.attributes().get("rowspan"); | |
int colSpan = StringUtils.isNotBlank(colSpanAttr) ? Integer.parseInt(colSpanAttr) : 0; | |
int rowSpan = StringUtils.isNotBlank(rowSpanAttr) ? Integer.parseInt(rowSpanAttr) : 0; | |
CellInfo cellInf = new CellInfo(colSpan, rowSpan); | |
rowInf.getCells().add(cellInf); | |
} | |
tableInf.getRows().add(rowInf); | |
} | |
mTables.add(tableInf); | |
} | |
} | |
public int visitCellStart(Cell cell) | |
{ | |
int tabIdx = mWordTables.indexOf(cell.getParentRow().getParentTable()); | |
int rowIdx = cell.getParentRow().getParentTable().indexOf(cell.getParentRow()); | |
int cellIdx = cell.getParentRow().indexOf(cell); | |
int colSpan = 0; | |
int rowSpan = 0; | |
if (tabIdx < mTables.size() && | |
rowIdx < mTables.get(tabIdx).getRows().size() && | |
cellIdx < mTables.get(tabIdx).getRows().get(rowIdx).getCells().size()) | |
{ | |
colSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getColSpan(); | |
rowSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getRowSpan(); | |
} | |
System.out.println(MessageFormat.format("{0}.{1}.{2} colspan={3}\t rowspan={4}", tabIdx, rowIdx, cellIdx, colSpan, rowSpan)); | |
return VisitorAction.CONTINUE; | |
} | |
private ArrayList<TableInfo> mTables = new ArrayList<>(); | |
private NodeCollection mWordTables; | |
} |
Konversikan ke Sel yang Digabungkan 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. Tetapi untuk situasi di mana sel digabungkan menjadi sel secara horizontal dengan lebarnya menggunakan flag gabungan, Aspose.Words menyediakan metode ConvertToHorizontallyMergedCells
untuk mengonversi sel. Metode ini hanya mengubah tabel dan menambahkan sel baru sesuai kebutuhan.
Contoh kode berikut menunjukkan metode di atas dalam operasi:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git. | |
Document doc = new Document(getMyDir() + "Table with merged cells.docx"); | |
Table table = doc.getFirstSection().getBody().getTables().get(0); | |
// Now merged cells have appropriate merge flags. | |
table.convertToHorizontallyMergedCells(); |