Table creation issue with document builder

Hi,

I’m trying to create the table in the attached document ‘expected.docx’ using the DocumentBuilder.

Here’s the Java code I’m using:

	Document d = new Document();
	DocumentBuilder b = new DocumentBuilder(d);
	b.moveToDocumentStart();
	b.startTable();
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(76.75));
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(76.75));
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(76.8));
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(115.2));
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(115.2));
	b.endRow();
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(115.15));
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(115.15));
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(115.2));
	b.insertCell();
	b.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(115.2));
	b.endTable();

The result document is ‘out.docx’.
But the result is not as expected. The created table is not even rectangular.

I tried to fix this with the following code by automatically generating ‘collspans’:

	Table table = (Table) d.getChildNodes(NodeType.TABLE, true).get(0);
	Set<Double> cellWidthSet = new HashSet<Double>();
	for (Row row : table.getRows()) {
		double cellPosition = 0;
		for (Cell cell : row.getCells()) {
			double cellWidth = cell.getCellFormat().getPreferredWidth().getValue();
			cellPosition += cellWidth;
			cellWidthSet.add(cellPosition);
		}
	}

	List<Double> expectedCellWidths = new ArrayList<Double>(cellWidthSet);
	Collections.sort(expectedCellWidths);

	for (Row row : table.getRows()) {
		int cellIndex = 0;
		Cell cell = row.getFirstCell();

		do {
			double cellWidth = cell.getCellFormat().getPreferredWidth().getValue();
			double expectedCellWidth = expectedCellWidths.get(cellIndex);
			if (cellWidth > expectedCellWidth) {
				cell.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(expectedCellWidth));
				if (cell.getCellFormat().getHorizontalMerge() == CellMerge.NONE) {
					cell.getCellFormat().setHorizontalMerge(CellMerge.FIRST);
				}

				Cell clonedCell = (Cell) cell.deepClone(false);
				clonedCell.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(cellWidth - expectedCellWidth));
				clonedCell.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS);

				row.insertAfter(clonedCell, cell);
			}
			cellIndex++;
			cell = (Cell) cell.getNextSibling();
		} while (cell != null);
	}

The result document is ‘out - corrected.docx’.
This does make the table square
But even though all the cell properties are the same as the document ‘expected.docx’ when opened in Microdoft Word, the cells widths are visually different even though their preferred widths are the same.

What am I missing to create the table correctly?

Thank you very much.

Best regards,

documents.zip (20.3 KB)

@pbost,

You can build logic on the following code to get the desired output:

Document d = new Document();
DocumentBuilder b = new DocumentBuilder(d);
b.moveToDocumentStart();
Table tbl = b.startTable();
b.insertCell();
b.getCellFormat().setWidth(76.75);
b.insertCell();
b.getCellFormat().setWidth(76.75);
b.insertCell();
b.getCellFormat().setWidth(76.8);
b.insertCell();
b.getCellFormat().setWidth(115.2);
b.insertCell();
b.getCellFormat().setWidth(115.2);
b.endRow();
b.insertCell();
b.getCellFormat().setWidth(115.15);
b.insertCell();
b.getCellFormat().setWidth(115.15);
b.insertCell();
b.getCellFormat().setWidth(115.2);
b.insertCell();
b.getCellFormat().setWidth(115.2);
b.endTable();

tbl.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS);

d.save("E:\\Documents\\19.9.docx");