Last column within the table not rendered correctly within the word document

Hi Team,

I loaded the attached HTML input file into the Document object as bytes and I have below logic that converts the HTML into EMF Image. The issue we are facing is that the last column within the Table is not rendered correctly within the EMF Image nor within the Document. I have attached a screenshot with the issue pointed out.

public void convertGridToImage() {
byte[] htmlBytes = Files.readAllBytes("Sample Table.html");	
HtmlLoadOptions options = new HtmlLoadOptions();
    		
Document doc = new Document(htmlBytes, options);
DocumentBuilder builder = new DocumentBuilder(doc);
   		
//update page properties like size and margin
PageSetup pageSetup = builder.getPageSetup();
updatePageSettings(pageSetup);

// For Last Paragraph within Document, set font size to 0 if no text
// so that it won't occupy the space after the table.
// Also, do page break between Table and Paragraph so that while
// saving 1st Document Page only Table is saved.
Section section = doc.getFirstSection();
Body body = section.getBody();
Paragraph lastPara = body.getLastParagraph();
String paratext = lastPara.getText();
if(StringUtils.isNullOrBlank(paratext)) {
    ParagraphFormat paraFmt = lastPara.getParagraphFormat();
    paraFmt.getStyle().getFont().setSize(0);
    paraFmt.setPageBreakBefore(true);
}

// Update Table Layout properties such as Margin, Padding and Size
TableCollection tables = body.getTables();
Table table = tables.get(0);
if (table != null) {
    // Reset left indent. since table might be shifted left.
    table.setLeftIndent(0);
    // Need to ensure table has fixed column widths
    table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS);
    //update table ROW and CELL Layout
    updateTableRowSettings(table);

    Node node = table.getLastRow().getLastChild();
    if (node != null && node.getNodeType() == NodeType.PARAGRAPH && "\uFEFF\r".equals(node.getText())) {
      node.remove();
    }

    //update Document Page height based on Table Height
    renderTablePart(doc);
}
    		
// Save as different formats
doc.save("Sample Table.docx", SaveFormat.DOCX);
doc.save("Sample Table.emf", SaveFormat.EMF);
}

private void updatePageSettings(PageSetup pageSetup) {
    double margin = 0;
    pageSetup.setLeftMargin(margin);
    pageSetup.setRightMargin(margin);
    pageSetup.setTopMargin(margin);
    pageSetup.setBottomMargin(margin);
    pageSetup.setFooterDistance(0);
    pageSetup.setHeaderDistance(0);

    double heightpt = ConvertUtil.pixelToPoint(822.0);
    double widthpt = ConvertUtil.pixelToPoint(1680.0);
    pageSetup.setPaperSize(PaperSize.CUSTOM);
    pageSetup.setPageWidth(widthpt);
    pageSetup.setPageHeight(heightpt);
}

private void updateTableRowSettings(Table table) throws Exception{
    double[] rowHeights = [25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 96.0];
    double[] colWidths = [190.0, 70.0, 98.0, 98.0, 98.0, 98.0, 106.0, 98.0, 98.0, 98.0, 98.0, 98.0, 98.0, 78.0, 78.0, 78.0, 98.0];

    for (Row row : table.getRows()) {
    	RowFormat rowFmt = row.getRowFormat();
    	int rowIndex = table.indexOf(row);
    	double rowHeight = ConvertUtil.pixelToPoint(rowHeights[rowIndex]);
    		
    	rowFmt.setAllowBreakAcrossPages(false);		
    	rowFmt.setHeight(rowHeight);
    	rowFmt.setHeightRule(HeightRule.EXACTLY);   
    		
    	for(Cell cell : row.getCells()) {
    		int colIndex = row.indexOf(cell);
    		double cellWidth = ConvertUtil.pixelToPoint(colWidths[colIndex]);
    			
    		CellFormat cellFmt = cell.getCellFormat();
    		cellFmt.setWidth(cellWidth);
    		cellFmt.setTopPadding(0);
    		cellFmt.setBottomPadding(0);
    	}
    }
}

private void renderTablePart(Document oneTableDoc) throws Exception
{
    // Set maximum allowed page height
    oneTableDoc.getFirstSection().getPageSetup().setPageHeight(1584);
    oneTableDoc.getFirstSection().getPageSetup().setPageWidth(1584);

    LayoutCollector collector = new LayoutCollector(oneTableDoc);
    LayoutEnumerator enumerator = new LayoutEnumerator(oneTableDoc);

    Table table = oneTableDoc.getFirstSection().getBody().getTables().get(0);

    // Calculate table size.
    // For demonstration purposes the example purposes the while table is on the same page.
    enumerator.setCurrent(collector.getEntity(table.getFirstRow().getFirstCell().getFirstParagraph()));
    int startPageIndex = enumerator.getPageIndex();
    // Move enumerator to a row.
    while (enumerator.getType()!= LayoutEntityType.ROW)
        enumerator.moveParent();

    double top = enumerator.getRectangle().y;
    double left = enumerator.getRectangle().x;

    // Move enumerator to the last row.
    enumerator.setCurrent(collector.getEntity(table.getLastRow().getFirstCell().getFirstParagraph()));
    int endPageIndex = enumerator.getPageIndex();
    // Move enumerator to a row.
    while (enumerator.getType()!= LayoutEntityType.ROW)
        enumerator.moveParent();

    double bottom = enumerator.getRectangle().y + enumerator.getRectangle().height;
    double right = enumerator.getRectangle().x + enumerator.getRectangle().width;

    // Reset margins
    PageSetup ps = oneTableDoc.getFirstSection().getPageSetup();
    ps.setPageWidth(ps.getPageWidth()-ps.getLeftMargin()-ps.getRightMargin());
    ps.setLeftMargin(0);
    ps.setRightMargin(0);
    ps.setPageHeight(ps.getPageHeight()-ps.getTopMargin()-ps.getBottomMargin());
    ps.setTopMargin(0);
    ps.setBottomMargin(0);

    // Set calculated width
    ps.setPageWidth(right - left);
    // Do not set page height if table spans several pages.
    if(startPageIndex == endPageIndex)
        ps.setPageHeight(bottom - top);

    oneTableDoc.updatePageLayout();
}

Attachment - Sample Table.zip (173.6 KB)

@oraspose The following code render the table properly on my side using the latest 23.12 version of Aspose.Words:

Document doc = new Document("C:\\temp\\in.html");
renderTablePart(doc);
// Save as different formats
doc.save("C:\\temp\\out.docx", SaveFormat.DOCX);
doc.save("C:\\temp\\out.emf", SaveFormat.EMF);
doc.save("C:\\temp\\out.png", SaveFormat.PNG);

out.zip (118.9 KB)

@alexey.noskov We are currently using ASPOSE.Words version 21.07 and we do not have any plans for upgrading to 23.12 version at the moment. Is there an alternative way to fix this issue?

@oraspose The same code works fine on my side with 21.7 version of Aspose.Words. Here are output documents produced by 21.7 version:
out.zip (111.8 KB)

Here is full code:

Document doc = new Document("C:\\temp\\in.html");
renderTablePart(doc);
// Save as different formats
doc.save("C:\\temp\\out.docx", SaveFormat.DOCX);
doc.save("C:\\temp\\out.emf", SaveFormat.EMF);
doc.save("C:\\temp\\out.png", SaveFormat.PNG);
private static void renderTablePart(Document oneTableDoc) throws Exception
{
    // Set maximum allowed page height
    oneTableDoc.getFirstSection().getPageSetup().setPageHeight(1584);

    LayoutCollector collector = new LayoutCollector(oneTableDoc);
    LayoutEnumerator enumerator = new LayoutEnumerator(oneTableDoc);

    Table table = oneTableDoc.getFirstSection().getBody().getTables().get(0);

    // Calculate table size.
    // For demonstration purposes the example purposes the while table is on the same page.
    enumerator.setCurrent(collector.getEntity(table.getFirstRow().getFirstCell().getFirstParagraph()));
    int startPageIndex = enumerator.getPageIndex();
    // Move enumerator to a row.
    while (enumerator.getType()!= LayoutEntityType.ROW)
        enumerator.moveParent();

    double top = enumerator.getRectangle().y;
    double left = enumerator.getRectangle().x;

    // Move enumerator to the last row.
    enumerator.setCurrent(collector.getEntity(table.getLastRow().getFirstCell().getFirstParagraph()));
    int endPageIndex = enumerator.getPageIndex();
    // Move enumerator to a row.
    while (enumerator.getType()!= LayoutEntityType.ROW)
        enumerator.moveParent();

    double bottom = enumerator.getRectangle().y + enumerator.getRectangle().height;
    double right = enumerator.getRectangle().x + enumerator.getRectangle().width;

    // Reset margins
    PageSetup ps = oneTableDoc.getFirstSection().getPageSetup();
    ps.setPageWidth(ps.getPageWidth()-ps.getLeftMargin()-ps.getRightMargin());
    ps.setLeftMargin(0);
    ps.setRightMargin(0);
    ps.setPageHeight(ps.getPageHeight()-ps.getTopMargin()-ps.getBottomMargin());
    ps.setTopMargin(0);
    ps.setBottomMargin(0);

    // Set calculated width
    ps.setPageWidth(right - left);
    // Do not set page height if table spans several pages.
    if(startPageIndex == endPageIndex)
        ps.setPageHeight(bottom - top);

    oneTableDoc.updatePageLayout();
}