简体   繁体   中英

How can I make HTML table footer take available space on each page when printing on multiple pages?

I like to print a very long table on multiple pages. On each page I have a fixed header, multiple entries in body section with random heights, and a footer. Random entries should not break across pages and the footer should use the available remaining space. I created a sample code with a print button. When I click on the print button, I want the orange box to start right after its preceding red box and take all the space to the bottom of the page. Any ideas how to fix the issue?

 const main = document.querySelectorAll(".table-body")[0]; const newDiv = document.createElement("div"); for (let i = 0; i < 30; i++) { newDiv.innerHTML += `<div class="box" style="height: ${getRandomIntInclusive(120,250)}px">Line ${i+1} </div>` } main.appendChild(newDiv); document.getElementById("print").addEventListener("click", () => { window.print(); }); function getRandomIntInclusive(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } 
 table { width: 100%; border: 1px solid blue; padding: 10px; } .table-body { border: 1px dashed green; padding: 10px; } .box { border: 1px solid red; page-break-inside: avoid; } table > tfoot > tr > td { border: 2px solid orange; } .table-footer { border: 1px solid black; min-height: 100px; vertical-align: top; } @media print { @page { size: letter; } #print { display: none; } } 
 <button id='print'>Print</button> <table> <thead> <tr> <th> Header </th> <tr> </thead> <tbody> <tr> <td> <div class='table-body'></div> </td> <tr> </tbody> <tfoot> <tr> <td> <div class='table-footer'>Footer</div> </td> <tr> </tfoot> </table> 

I was not able to solve the issue using a table so I ended up solving my problem using divs. I kept track of the random height of divs on each page and assigned the remaining space to the footer. My footers have some min-height limitation to ensure that I have a footer on each page. The content of each page is placed in another div to give me more control on styling each page; eg: page-break-after and overflow . The solution is not ideal and hoping that someone comes with a better approach but it satisfies my need for the moment. Below you can find the updated code:

 const main = document.getElementById("main"); const newDiv = document.createElement("div"); const paperHeight = 11 // paper height in inch const paperMargin = 1; // sum of top and bottom paper margins in inch const overflow = 0.11; // used to protect page overflow to the next page const dpi = 96; // Display dots per inch (DPI) const maxHeight = (paperHeight - paperMargin) * dpi; // max page height const footerMinHeight = 40; // Min height of footer const headerHeight = 100; // Height of header in px const numOfItems = 20; // Number of items let j = 0; let items = ''; let pageCount = 1; do { items += `<div class="page" style="max-height: ${paperHeight - paperMargin - overflow}in"><div class="box header" style="height: ${headerHeight}px">Page ${pageCount} - Header</div>`; let pageHeight = headerHeight; do { const elementHeight = getRandomIntInclusive(60, 250); if (elementHeight + pageHeight > maxHeight - footerMinHeight || j === numOfItems) { items += `<div class="box footer" style="height: ${maxHeight - pageHeight}px">Footer</div></div>`; break; } else { pageHeight += elementHeight; j++; } items += `<div class="box" style="height: ${elementHeight}px">Item ${j} </div>`; } while (j <= numOfItems) pageCount++; } while (j < numOfItems) newDiv.innerHTML = items; main.appendChild(newDiv); document.getElementById("print").addEventListener("click", () => { window.print(); }); function getRandomIntInclusive(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } 
 * { box-sizing: border-box; } .page { border: 1px dashed green; page-break-after: always; overflow: hidden; } .box { border-bottom: 1px solid red; } .header { background: #e6ffe6 } .footer { background: #fdfed6; } @media print { @page { size: letter; margin: 0.5in; } #print { display: none; } } 
 <button id='print'>Print</button> <div id='main'></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM