Hi @alexey.noskov,
I tried the same logic with another test case(attached files) but this time the generated DOCX document had Tables rendered into multiple sections or pages when using the same LayoutCollector logic. We are also aware about the restriction on the Document Page size from this discussion which is 1584pt but the Page height was not set explicitly. The default Document Page height picked up by the framework is 1056px and still we could see the Table being rendered into multiple sections.
Any idea what is happening during the rendering process? We could notice from the below logic that the bottom value is showing 93pt while top is 0 and we assume it is because of that the table is split.
Sample Code used for generating DOCX output:
private void convertToImage(byte[] htmlBytes) {
try {
HtmlLoadOptions options = new HtmlLoadOptions();
Document doc = new Document(htmlBytes, options);
DocumentBuilder builder = new DocumentBuilder(doc);
PageSetup pageSetup = builder.getPageSetup();
//update page properties like size and margin
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);
//update table ROW and CELL Layout
updateTableRowSettings(table);
//update Document Page height based on Table Height
renderTablePart(doc);
... other logic
}
// save as DOCX format
OoxmlSaveOptions ooxmlSaveOptions = new OoxmlSaveOptions();
doc.save("Sample Table 1.docx", ooxmlSaveOptions);
} catch(Exception ex) {
throw new IllegalStateException(ex.getMessage(), ex);
}
}
private void updatePageSettings(PageSetup pageSetup) {
double margin = 0;
pageSetup.setLeftMargin(margin);
pageSetup.setRightMargin(margin);
pageSetup.setTopMargin(margin);
pageSetup.setBottomMargin(margin);
double widthpx = 402;
double widthpt = ConvertUtil.pixelToPoint(widthpx);
pageSetup.setPaperSize(PaperSize.CUSTOM);
pageSetup.setPageWidth(widthpt);
}
private void updateTableRowSettings(Table table) throws Exception{
// set the default table top and bottom padding values
List<Double> colWidths = new ArrayList<>();
colWidths.add(161.28);
colWidths.add(85);
colWidths.add(85);
colWidths.add(70);
for (Row row : table.getRows()) {
RowFormat rowFmt = row.getRowFormat();
rowFmt.setAllowBreakAcrossPages(false);
rowFmt.setHeight(ConvertUtil.pixelToPoint(25.0));
rowFmt.setHeightRule(HeightRule.EXACTLY);
for(Cell cell : row.getCells()) {
int colIndex = row.indexOf(cell);
double cellWidth = colWidths.get(colIndex);
CellFormat cellFmt = cell.getCellFormat();
cellFmt.setWidth(ConvertUtil.pixelToPoint((cellWidth));
cellFmt.setTopPadding(0);
cellFmt.setBottomPadding(0);
}
}
}
private void renderTablePart(Document oneTableDoc) throws Exception
{
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()));
// 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()));
// 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);
ps.setPageHeight(bottom - top);
oneTableDoc.updatePageLayout();
}
Attachment: Sample Table 1.7z (14.9 KB)