Birleştir Tabloları Hücreleri

Bazen bir tablodaki bazı satırlar bir başlık veya tam tablo genişliğini kaplayan büyük metin blokları gerektirir. İyi bir tablo tasarımı için kullanıcı, birkaç tablo hücresini tek bir hücrede birleştirebilir. Aspose.Words, tüm giriş formatlarında çalışırken birleştirilmiş hücreleri destekler, hatta html içeriği içe aktarırken bile.

Tablo Hücrelerini Birleştirme Nasıl Yapılır?

Aspose.Words ‘da birleştirilmiş hücreler aşağıdaki özelliklerle temsil edilir: CellFormat sınıfı

  • HorizontalMerge bir hücrenin hücrelerin yatay birleşiminden bir parçası olup olmadığını açıklar
  • VerticalMerge hücrenin bir hücrelerin dikey birleşmesinin bir parçası olup olmadığını açıklar

Bu özelliklerin değerleri hücre birleşim davranışını belirler:

work-with-merged-cells-aspose-words-java

Hücre Birleşip Birleşmediğini Kontrol Etmek

Bir hücrenin birleştirilmiş hücrelerin bir dizisinin parçası olup olmadığını kontrol etmek için, sadece HorizontalMerge ve VerticalMerge özelliklerini kontrol ederiz.

Aşağıdaki kod örneğinde yatay ve dikey hücre birleşimi türü nasıl yazdırılır gösterilmektedir:

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

DocumentBuilder Kullanırken Tablo Hücrelerini Birleştirin

Bir DocumentBuilder ile oluşturulan tabloda hücreleri birleştirmeniz için, her birinde birleştirmenin gerçekleşmesi beklenen hücreler için uygun birleştirme türünü ayarlamanız gerekir – önce CellMerge.First sonra CellMerge.Previous.

Ayrıca, birleştirme ayarını gereksiz olan hücrelerde temizlemeyi hatırlamalısınız - bu, CellMerge.None‘a ilk birleştirme olmayan hücreyi ayarlayarak yapılabilir. Böyle yapılmazsa tablo içindeki tüm hücreler birleşir.

Aşağıdaki kod örneği, iki satır içeren bir tablo oluşturmak için nasıl kullanılacağını göstermektedir ve ilk satırdaki hücreler yatay olarak birleştirilir:

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

Aşağıdaki kod örneğinde ilk sütundaki hücrelerin dikey olarak birleştirilmesiyle nasıl iki sütunlu bir tablo oluşturulduğu gösterilmiştir:

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

Diğer Durumlarda Tablo Hücrelerini Birleştir

Diğer durumlarda DocumentBuilder kullanılmadığında, örneğin mevcut bir tabloya, bu şekilde hücrelerin birleştirilmesi o kadar kolay olmayabilir. Bunun yerine, hücrelere birleştirme özellikleri uygulayacak temel işlemleri kapsayan bir yöntemle sarabiliriz ki bu, görevi çok daha kolay hale getirir. Bu yöntem, bir tablodaki hücrelerin bir aralığını birleştirmek için çağrılan Birleştir otomasyon yöntemine benzer.

Aşağıdaki kod belirtilen aralıkta tablo hücrelerini birleştirerek başlayacak verilen hücrede ve bitiş hücresinde sonlandıracak. Bu durumda aralığın birden fazla satır veya sütun kapsayabileceği:

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

Aşağıdaki kod örneği iki belirtilen hücreler arasındaki bir hücre aralığını birleştirme gösteriyor:

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

HTML Tablosunda Dikey ve Yatay Birleştirilmiş Hücreler

Önceki makalelerde söylediğimiz gibi, bir tablo Microsoft Word içindeki bağımsız satırların bir kümesidir. Her satır diğer satırlardaki hücrelerden bağımsız bir dizi hücreye sahiptir. Böylece, Microsoft Word tablosunda böyle bir nesne yoktur ‘bir sütun’, ve '’ 1. sütun '’ her satırdaki ilk hücrelerin kümesi gibi şeydir 1. Bu kullanıcıların örneğin 1. satırda iki hücre - 2 cm ve 1 cm, ve 2. satırda iki farklı hücre - genişlikleri 1 cm ve 2 cm olan bir tabloya sahip olmasına izin verir. Ve Aspose.Words bu tablo kavramını destekler.

HTML’de bir tablo esasen farklı bir yapıya sahiptir: Her satır aynı sayıda hücreye sahiptir ve (görev için önemlidir) her hücre karşılık gelen sütunun genişliğini gösterir, tüm hücreler bir sütunda olduğu gibi. Eğer HorizontalMerge ve VerticalMerge yanlış bir değer döndürürse, aşağıdaki kod örneğini kullanın:

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

HorizontallyMergedCells’e Dönüştür

Bazen birleştirilmiş hücrelerin hangilerinin olduğunu tespit etmek mümkün değildir çünkü bazı yeni sürümler Microsoft Word daha fazla yatay olarak birleştirilmiş olduğunda birleştirme bayraklarını kullanmaz. Ancak hücrelerin genişlikleri ile yatay olarak bir hücreye birleştirilirken “birleştirme bayrakları” kullanılarak oluşturulan durumlarda Aspose.Words sağlar ConvertToHorizontallyMergedCells yöntemini hücrelere dönüştürmek için. Bu yöntem tabloyu yalnızca dönüştürür ve gerektiğinde yeni hücreler ekler.

Aşağıdaki kod örneği yukarıdaki yöntemi çalışırken göstermektedir:

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