HTML页脚与未知页数的页码(动态生成的数据)
我正在把Crystal Reports转换成HTML,但在页脚上遇到了问题。
我无法将页脚固定在每一页生成或打印的底部。布局(例如表格)将由后端C#动态填充。它们有时会错位(在我的情况下是A4尺寸)或只是随着内容漂浮。
我的目标是在每一页的底部显示干净的页脚(包含页码),且不让页面内容溢出到页脚。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dEMO</title>
<style>
*{
box-sizing:border-box;
}
body{
margin:0;
padding:8px;
background:#f4f4f4;
font-family:Arial,sans-serif;
font-size:12px;
}
/* =========================
A4 PAGE
========================== */
@page{
size:A4;
margin:10mm;
}
.page{
width:210mm;
min-height:297mm;
margin:0 auto;
background:#fff;
border:1px solid #dcdcdc;
padding:10mm;
/* reserve space for footer */
padding-bottom:30mm;
position:relative;
}
@media print{
body{
background:white;
padding:0;
margin:0;
}
.page{
border:none;
margin:0 auto;
}
table{
page-break-inside:auto;
}
tr{
page-break-inside:avoid;
page-break-after:auto;
}
thead{
display:table-header-group;
}
tfoot{
display:table-footer-group;
}
}
/* =========================
HEADER
========================== */
caption{
text-align: center;
margin-bottom:8px;
}
caption a{
text-decoration:none;
color:#4CAF50;
font-size:0.9em;
}
.header{
display:flex;
justify-content:space-between;
margin-bottom:8px;
}
.company-section{
display:flex;
gap:15px;
}
.company-logo{
width:60px;
height:60px;
object-fit:contain;
}
.company-details{
line-height:18px;
}
.company-name{
font-weight:bold;
font-size:22px;
}
.right-header{
width:300px;
}
.report-title{
text-align:right;
font-size:22px;
font-weight:bold;
color:#8b0000;
border-bottom:1px solid purple;
margin-bottom:10px;
padding-bottom:2px;
}
.info-table{
width:100%;
border-collapse:collapse;
}
.info-table td{
padding:3px 0;
}
.info-label{
width:120px;
}
.info-colon{
width:15px;
}
.info-value{
text-align:right;
}
.info-value-code{
text-align:right;
font-weight:bold;
color:#8b0000;
}
/* =========================
CUSTOMER DETAILS
========================== */
.customer-section{
margin-top:5px;
margin-bottom:5px;
line-height:18px;
}
.customer-row{
display:flex;
}
.customer-label{
width:70px;
}
/* =========================
MAIN TABLE
========================== */
.bbs-table{
width:100%;
border-collapse:collapse;
table-layout:fixed;
}
.bbs-table th{
background-color:#8d8d8d;
color:white;
padding:6px 4px;
font-size:12px;
font-weight:bold;
border:1px solid #8d8d8d;
}
.bbs-table td{
border:1px solid #c0c0c0;
padding:4px;
text-align:center;
vertical-align:middle;
}
.sub-text{
display:block;
font-size:10px;
color:#eaeaea;
}
.weight-row td{
background-color:#8d8d8d;
color:white;
font-weight:bold;
padding:4px;
border-top:4px solid #f3f3f3;
}
.shape-cell{
width:140px;
text-align:center;
vertical-align:middle;
}
.shape-image{
width:120px;
height:auto;
object-fit:contain;
display:block;
margin:auto;
}
/* =========================
PRODUCT TABLE
========================== */
.product-table{
width:100%;
border-collapse:collapse;
margin-top:2px;
}
.product-table th{
background:#8d8d8d;
color:white;
padding:5px;
text-align:left;
}
.product-table td{
padding:4px 6px;
border:none;
}
.right{
text-align:right;
}
.muted{
display:block;
font-size:10px;
color:#777;
}
.summary-row td{
background:#8a8a8a;
color:white;
font-weight:bold;
text-align:center;
padding:4px;
}
.total-weight{
text-align:center;
}
.grand-total-section{
margin-top:2px;
}
.grand-total-line{
border-top:1px solid #8d8d8d;
margin-bottom:4px;
}
.grand-total-row{
display:grid;
grid-template-columns:15% 45% 15% 25%;
align-items:center;
font-weight:bold;
font-size:12px;
}
.grand-total-label{
padding-left:6px;
}
.grand-total-pcs{
text-align:center;
}
.grand-total-wgt{
text-align:right;
padding-right:6px;
}
/* =========================
FOOTER
========================== */
.report-footer{
position:absolute;
bottom:10mm;
left:10mm;
right:10mm;
font-size:11px;
color:#444;
}
.footer-line{
border-top:1px solid #8d8d8d;
margin-bottom:6px;
}
.footer-content{
display:flex;
justify-content:space-between;
align-items:center;
}
.footer-item{
min-width:180px;
}
.footer-label{
font-weight:bold;
}
</style>
</head>
<body>
<div class="page">
<table summary="Total Weight" style="width: 100%;">
<caption>
<a href="http://bendplus.com">
DEMO
</a>
</caption>
<tbody>
<tr>
</tr>
</tbody>
</table>
<!-- =========================
HEADER
========================== -->
<div class="header">
<!-- LEFT -->
<div class="company-section">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTb11uhYlc60nFSkWl4pY1SHfEJXB2gdIwtTA&s" class="company-logo">
<div class="company-details">
<div class="company-name">
xxCompanyName
</div>
<div>
xxCompanyAddress
</div>
<div>
xxCompanyMail
</div>
<div>
xxCompanyWeb
</div>
</div>
</div>
<!-- RIGHT -->
<div class="right-header">
<div class="report-title">
DEMO
</div>
<table class="info-table">
<tr>
<td class="info-label">DEMO</td>
<td class="info-colon">:</td>
<td class="info-value-code">xxCtrlCode</td>
</tr>
<tr>
<td class="info-label">DEMO</td>
<td class="info-colon">:</td>
<td class="info-value">xxProjectCode</td>
</tr>
<tr>
<td class="info-label">DEMO</td>
<td class="info-colon">:</td>
<td class="info-value">xxDeliveryDate</td>
</tr>
<tr>
<td class="info-label">DEMO</td>
<td class="info-colon">:</td>
<td class="info-value">xxDwgRef</td>
</tr>
<tr>
<td class="info-label">DEMO</td>
<td class="info-colon">:</td>
<td class="info-value">xxDwgNo</td>
</tr>
<tr>
<td class="info-label">Description</td>
<td class="info-colon">:</td>
<td class="info-value">xxDescription</td>
</tr>
</table>
</div>
</div>
<!-- =========================
CUSTOMER
========================== -->
<div class="customer-section">
<div class="customer-row">
<div class="customer-label">Customer</div>
<div>: xxCustName</div>
</div>
<div class="customer-row">
<div class="customer-label">Project</div>
<div>: xxProject</div>
</div>
</div>
<!-- =========================
MAIN TABLE
========================== -->
<table class="bbs-table">
<thead>
<tr>
<th>DEMO</th>
<th>DEMO</th>
<th>
DEMO
<span class="sub-text">MM</span>
</th>
<th>Qty</th>
<th>DEMO</th>
<th>Length</th>
<th>
DEMO
<span class="sub-text">MM</span>
</th>
<th>
DEMO
<span class="sub-text">Kgs</span>
</th>
<th>
DEMO
<span class="sub-text">Kgs</span>
</th>
<th style="width: 18%;">Shape</th>
</tr>
</thead>
<tbody id="DEMO">
<tr>
<td colspan="10">###Notes</td>
</tr>
<tr>
<td>###SEQ</td>
<td>###DEMO</td>
<td>###DEMO</td>
<td>###Qty</td>
<td>###DEMO</td>
<td>###Length</td>
<td>###DEMO</td>
<td>###DEMO</td>
<td>###DEMO</td>
<td rowspan="2">###DEMO</td>
</tr>
<tr>
<td colspan="6" style="color: #8b0000;text-align: left;">###Remarks</td>
<td colspan="3" style="color: blue;text-align: right;">###SurchargeGrp</td>
</tr>
</tbody>
</table>
<!-- =========================
PRODUCT TABLE
========================== -->
<table class="product-table">
<thead>
<tr>
<th style="width:10%">DEMO</th>
<th style="width:35%">DEMO</th>
<th style="width:35%">DEMO</th>
<th style="width:10%">DEMO</th>
<th style="width:10%" class="right">DEMO</th>
</tr>
</thead>
<tbody id="bbsSummaryTemplate">
<tr style="background-color: cornsilk;">
<td style="width: 50%;color: #8b0000;text-align: left;">###DEMO</td>
<td style="color: fuchsia;">SubTotal : </td>
<td colspan="2" style="color:#8b0000;font-weight: bold;">###DEMO</td>
<td style="color: #8b0000;font-weight: bold;">###DEMOt</td>
</tr>
<tr>
<td>###DEMO</td>
<td>###DEMO
<span class="muted" style="display: block;">###DEMO</span>
</td>
<!-- <td>###DEMO</td> -->
<!--<td>###DEMO</td>-->
<td>###DEMO</td>
<td>DEMO</td>
<td>###DEMO</td>
</tr>
<tr>
<td></td>
<td></td>
<td style="text-align: left;">###DEMO</td>
</tr>
</tbody>
</table>
<!-- GRAND TOTAL -->
<div class="grand-total-section">
<div class="grand-total-line"></div>
<div class="grand-total-row">
<div></div>
<div class="grand-total-label">
</div>
<div>GRAND TOTAL : </div>
<div class="grand-total-wgt">
###GrandTotalWgt
</div>
</div>
</div>
<!-- =========================
FOOTER
========================== -->
<div class="report-footer">
<div class="footer-line"></div>
<div class="footer-content">
<div class="footer-item">
<span class="footer-label">B+ Code :</span>
<span>xxCtrlCode</span>
</div>
<div class="footer-item">
<span class="footer-label">Release :</span>
<span>xxReleaseNo</span>
</div>
<div class="footer-item">
<span class="footer-label">Page Wgt :</span>
<span>xxPageWgt</span>
</div>
</div>
</div>
</div>
</body>
</html>
解决方案
Your current footer uses:
.report-footer {
position: absolute;
bottom: 10mm;
}
这只对一个 .page div 有效。当浏览器将内容分割时,它不会在每个打印页面上自动重复。HTML/CSS打印不像Crystal Reports那样分页。
要在每一页打印时显示页脚,请在 @media print 内使用 position: fixed:
@media print {
@page {
size: A4;
margin: 15mm 10mm 25mm 10mm;
}
body {
margin: 0;
padding: 0;
background: white;
}
.page {
width: auto;
min-height: auto;
border: none;
margin: 0;
padding: 0;
padding-bottom: 25mm;
}
.report-footer {
position: fixed;
bottom: 8mm;
left: 10mm;
right: 10mm;
height: 15mm;
background: white;
}
table {
page-break-inside: auto;
}
tr {
page-break-inside: avoid;
page-break-after: auto;
}
thead {
display: table-header-group;
}
}
要添加页码,请使用以下内容:
.report-footer::after {
content: "Page " counter(page);
float: right;
}
重要提示:在Chrome/Edge中对 counter(page) 的浏览器支持并不可靠。如果你需要“准确的页码和保证的页脚定位”,请使用服务器端的HTML-to-PDF引擎生成PDF,例如 wkhtmltopdf、DinkToPdf、QuestPDF、Rotativa,或 Puppeteer。
另外,在打印时请移除 .page 的固定A4大小。这部分会造成大量的对齐问题:
.page {
width: 210mm;
min-height: 297mm;
}
让浏览器通过 @page 来处理打印时的页面大小,而不是通过固定的 .page 容器。你当前的结构使用一个 .page 包裹,并且页脚是绝对定位的,因此无法在生成的每一页上自然重复页脚。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。