Given the following task: In a table consisting of several rows and columns, a specific column should be deleted. The challenge hereby is that some rows contain merged cells.
As an example assume this table where to delete the 2nd column:
- Code: Select all
+-------------------------+
| C1 | C2 | C3 | C4 |
+-------------------------+
| Merged | C5 |
+-------------------------+
The desired result should be this table:
- Code: Select all
+-------------------+
| C1 | C3 | C4 |
+-------------------+
| Merged | C5 |
+-------------------+
To achieve this, my solution is to first split all merged cells in the table to ensure each row contains the same number of columns (cells).
- Code: Select all
+-------------------------+
| C1 | C2 | C3 | C4 |
+-------------------------+
| Merged | | | C5 |
+-------------------------+
Now I delete the 2nd column. As a result I expect the following table:
- Code: Select all
+-------------------+
| C1 | C3 | C4 |
+-------------------+
| Merged | | C5 |
+-------------------+
Finally undo the cell splitting, i.e. redo the merge.
- Code: Select all
+-------------------+
| C1 | C3 | C4 |
+-------------------+
| Merged | C5 |
+-------------------+
Here is the sample code I used:
- Code: Select all
private static void test() {
Document document = new Document();
Table table = new Table(document);
table.resetCells(2,4);
try {
table.setColumnWidth(0, 90f, CellWidthType.Point);
table.setColumnWidth(1, 80f, CellWidthType.Point);
table.setColumnWidth(2, 80f, CellWidthType.Point);
table.setColumnWidth(3, 70f, CellWidthType.Point);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
// 1st row
table.getRows().get(0).getCells().get(0).addParagraph().appendText("c1");
table.getRows().get(0).getCells().get(1).addParagraph().appendText("c2");
table.getRows().get(0).getCells().get(2).addParagraph().appendText("c3");
table.getRows().get(0).getCells().get(3).addParagraph().appendText("c4");
// 2nd row
table.getRows().get(1).getCells().get(0).addParagraph().appendText("merged");
table.getRows().get(1).getCells().get(3).addParagraph().appendText("c5");
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("Initial table structure");
printTableInfo(table);
// merge 1st to 3rd cell in 2nd row; at this point I expect the table to be the same as in the attached sample document.
table.applyHorizontalMerge(1, 0, 2);
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("Table structure after 1st merge");
printTableInfo(table);
// split merged cell in 2nd row
table.getRows().get(1).getCells().get(0).splitCell(3, 1);
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("Table structure after splitting");
printTableInfo(table);
// remove 2nd cell from both rows
table.getRows().get(0).getCells().removeAt(1);
table.getRows().get(1).getCells().removeAt(1);
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("Table structure after removing 2nd column");
printTableInfo(table);
// merge the 1st to 2nd cell in 2nd row
table.applyHorizontalMerge(1, 0, 1);
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("Table structure after 2nd merge");
printTableInfo(table);
Section section = document.addSection();
section.getTables().add(table);
document.saveToFile("Generated.docx", FileFormat.Docx);
document.dispose();
}
private static void printTableInfo(final Table table) {
for (int rowIndex = 0; rowIndex < table.getRows().getCount(); rowIndex++) {
TableRow row = table.getRows().get(rowIndex);
System.out.printf("\trow %d (%d columns)\n", rowIndex, row.getCells().getCount());
for (int cellIndex = 0; cellIndex < row.getCells().getCount(); cellIndex++) {
TableCell cell = row.getCells().get(cellIndex);
System.out.printf("\t\tcell %d: width = %f, span = %d\n", cellIndex, cell.getCellWidth(), cell.getGridSpan());
}
}
}
However, the result is really not what I have in mind as you can see from the generated document "Generated.docx".
I analyzed the table structure after each step and there are some things I do not understand and consider them as errors:
- Code: Select all
Initial table structure
row 0 (4 columns)
cell 0: width = 90,000000, span = 1
cell 1: width = 80,000000, span = 1
cell 2: width = 80,000000, span = 1
cell 3: width = 70,000000, span = 1
row 1 (4 columns)
cell 0: width = 90,000000, span = 1
cell 1: width = 80,000000, span = 1
cell 2: width = 80,000000, span = 1
cell 3: width = 70,000000, span = 1
----------------------------------------------------------------------------------------
Table structure after 1st merge
row 0 (4 columns)
cell 0: width = 90,000000, span = 1
cell 1: width = 80,000000, span = 1
cell 2: width = 80,000000, span = 1
cell 3: width = 70,000000, span = 1
row 1 (4 columns)
cell 0: width = 250,000000, span = 1
cell 1: width = 0,000000, span = 1
cell 2: width = 0,000000, span = 1
cell 3: width = 70,000000, span = 1
----------------------------------------------------------------------------------------
Table structure after splitting
row 0 (4 columns)
cell 0: width = 90,000000, span = 2
cell 1: width = 80,000000, span = 1
cell 2: width = 80,000000, span = 1
cell 3: width = 70,000000, span = 1
row 1 (6 columns)
cell 0: width = 83,349998, span = 1
cell 1: width = 83,349998, span = 2
cell 2: width = 83,349998, span = 1
cell 3: width = 0,000000, span = 1
cell 4: width = 0,000000, span = 1
cell 5: width = 70,000000, span = 1
----------------------------------------------------------------------------------------
Table structure after removing 2nd column
row 0 (3 columns)
cell 0: width = 90,000000, span = 2
cell 1: width = 80,000000, span = 1
cell 2: width = 70,000000, span = 1
row 1 (5 columns)
cell 0: width = 83,349998, span = 1
cell 1: width = 83,349998, span = 1
cell 2: width = 0,000000, span = 1
cell 3: width = 0,000000, span = 1
cell 4: width = 70,000000, span = 1
----------------------------------------------------------------------------------------
Table structure after 2nd merge
row 0 (3 columns)
cell 0: width = 90,000000, span = 2
cell 1: width = 80,000000, span = 1
cell 2: width = 70,000000, span = 1
row 1 (5 columns)
cell 0: width = 166,699997, span = 1
cell 1: width = 0,000000, span = 1
cell 2: width = 0,000000, span = 1
cell 3: width = 0,000000, span = 1
cell 4: width = 70,000000, span = 1
After the 1st merge operation (merge 1st to 3rd cell in 2nd row), I expected this result:
- Code: Select all
Table structure after 1st merge
row 0 (4 columns)
cell 0: width = 90,000000, span = 1
cell 1: width = 80,000000, span = 1
cell 2: width = 80,000000, span = 1
cell 3: width = 70,000000, span = 1
row 1 (2 columns)
cell 0: width = 250,000000, span = 3
cell 1: width = 70,000000, span = 1
Obviously the method "applyHorizontalMerge()" does some strange things here.
Things get even worse when I split the merged cell by calling method "splitCell()". Suddenly the 1st row contains a merge cell and 2nd row now consists of 6 cells and the 2nd cell seems to be even merged.
This is a complete mess to me.
Is there a bug in Spire.Doc for Java?
Did I something wrong?
Kind regards,
Marcus