danfickle / danfickle/openhtmltopdf

Calculated rendered height of html document a bit off when more than one page

Open
#924 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
2.2k
Forks
423
PR merge metrics
No merged PRs in 30d

Description

Hello!

Using version `1.0.10`, I am trying to get a PDF printout to be printed by thermal printers (with roll paper).

I have not set any CSS width or height values to any of the HTML elements, instead I am setting the `PdfRendererBuilder#useDefaultPageSize` method with my desired width and height values in MM.

The width is fixed and set to 80mm, but I need to calculate the rendered height of the document to give it to the above-mentioned method, to avoid splitting my printout into several pages, resulting in the printer cutting the paper at the end of every page. In other words I need a long continious one page PDF.

To achieve this I used the suggestions mentioned [here](https://github.com/danfickle/openhtmltopdf/issues/427), and it works, but not in all cases and as precisely as I expect.

**The problem is that** only when the content fits in one page (`PageBox`) (a default page height is internally set, regardless of HTML page having no heights set, resulting in generation of multiple pages when the content is large), the calculated height works correctly, but **when it is greater that one page, I get an extra blank space** (space between the bottom of my `.container` HTML element and the bottom of the `body` element) added to the bottom of the rendered PDF, which grows in height every couple of pages being added (3 to be more precise).

I will share with you a simplified snippet of my HTML and the code, and also a simple visual representation of what I get as the result.

**HTML to be rendered (I have added the red body bg to be visible in visual outcome):**
```

Printout


@page {
margin: 0;
}

body {
background-color: #ff0000;
}

.container * {
page-break-inside: avoid;
}

.container {
padding: 5mm;
overflow: hidden;
page-break-inside: avoid;
background-color: white;
}


HEADER CONTENT


MAIN CONTENT


FOOTER CONTENT

```

**Calculation of the rendered height and assigning it to the builder:**
```
private static void createPdfForPrinting(OutputStream outputStream, Document document)
throws IOException {

PdfRendererBuilder pdfBuilder = new PdfRendererBuilder();

try (PdfBoxRenderer pdfRenderer = pdfBuilder
.withW3cDocument(document, "/")
.useFastMode()
.toStream(outputStream)
.buildPdfRenderer()) {

pdfRenderer.layout();
Layer mainLayer = pdfRenderer.getRootBox().getContainingLayer();
float renderedHeight = findMaxLayerY(mainLayer);
float pageHeight = convertToMillimeters(renderedHeight);

pdfBuilder.useDefaultPageSize(80, pageHeight, BaseRendererBuilder.PageSizeUnits.MM)
.run();
}
}

private static int findMaxLayerY(Layer layer) {
int maxLayerY = layer.getMaster().getAbsY() + layer.getMaster().getHeight();

int maxChildY = layer.getChildren()
.stream()
.mapToInt(RendererUtil::findMaxLayerY)
.max()
.orElse(0);

return Math.max(maxChildY, maxLayerY);
}

private static float convertToMillimeters(float pixels) {
final float PDF_DOTS_PER_PIXEL = 20.0f;
final float MM_PER_INCH = 25.4f;
final int PIXELS_PER_INCH = 96;
return (pixels / PDF_DOTS_PER_PIXEL) * MM_PER_INCH / PIXELS_PER_INCH;
}
```
**Simple visual representation of the problem:**
![printouts](https://user-images.githubusercontent.com/5829938/228951574-fa91308a-00b9-4dd8-8be9-e201f64704d6.jpg)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.