fix footer pdf

This commit is contained in:
Mateusz Gruszczyński
2026-09-12 00:12:47 +02:00
parent c5e01916c8
commit 090acc9559
+32 -6
View File
@@ -101,10 +101,13 @@ function alignFooterToLastPage(doc, pageHeightMm, marginMm) {
if (!documentRoot || !spacer || !footer) return;
spacer.style.height = "0px";
footer.style.removeProperty("margin-top");
const pxPerMm = mmToPx(doc);
const pageContentHeight = (Number(pageHeightMm) - (2 * Number(marginMm))) * pxPerMm;
const footerHeight = footer.getBoundingClientRect().height;
const footerMarginTop = Number.parseFloat(doc.defaultView?.getComputedStyle(footer).marginTop || "0") || 0;
const bottomGuard = 1.5 * pxPerMm;
if (!Number.isFinite(pageContentHeight) || pageContentHeight <= footerHeight || footerHeight <= 0) return;
const rootTop = documentRoot.getBoundingClientRect().top;
@@ -115,12 +118,31 @@ function alignFooterToLastPage(doc, pageHeightMm, marginMm) {
? lastPageBreak.getBoundingClientRect().bottom - rootTop
: 0;
// A forced break starts a fresh page, so only the final segment determines
// where the one-time footer lands on the last printed page.
const finalSegmentHeight = Math.max(0, footerTop - finalSegmentStart);
const positionOnPage = ((finalSegmentHeight % pageContentHeight) + pageContentHeight) % pageContentHeight;
let spacerHeight = pageContentHeight - positionOnPage - footerHeight;
if (spacerHeight < -0.25) spacerHeight += pageContentHeight;
// Measure the end of document content, not the footer box. The footer's
// top margin may be reduced on a tight last page so it does not create an
// otherwise unnecessary extra page.
const contentEnd = Math.max(0, footerTop - footerMarginTop - finalSegmentStart);
const positionOnPage = ((contentEnd % pageContentHeight) + pageContentHeight) % pageContentHeight;
const available = pageContentHeight - positionOnPage;
let actualMarginTop = footerMarginTop;
let spacerHeight;
if (available >= footerHeight + bottomGuard) {
// Keep the normal footer gap when possible, but shrink it before moving
// the footer to another page. Leave a small guard against print rounding.
actualMarginTop = Math.min(
footerMarginTop,
Math.max(0, available - footerHeight - bottomGuard),
);
spacerHeight = available - footerHeight - actualMarginTop - bottomGuard;
} else {
// The footer itself cannot fit on the current page. Align it near the
// bottom of the next page while preserving its normal top gap.
spacerHeight = available + pageContentHeight - footerHeight - actualMarginTop - bottomGuard;
}
footer.style.marginTop = `${Math.max(0, actualMarginTop)}px`;
spacer.style.height = `${Math.max(0, spacerHeight)}px`;
}
@@ -175,6 +197,8 @@ function printStyles(cssSize, pageWidthMm, marginMm, preserveColors) {
margin: 0;
padding: 0;
border: 0;
break-after: avoid-page;
page-break-after: avoid;
}
.pdf-generated-footer {
box-sizing: border-box;
@@ -185,6 +209,8 @@ function printStyles(cssSize, pageWidthMm, marginMm, preserveColors) {
font: 500 7.5pt/1.2 Inter, ui-sans-serif, system-ui, sans-serif;
letter-spacing: .01em;
text-align: center;
break-before: avoid-page;
page-break-before: avoid;
break-inside: avoid;
page-break-inside: avoid;
}