我已经在谷歌上来回搜索了几个小时了,出于完全的沮丧,打印表格的看似简单的基本任务,以便以理智的方式分页符似乎完全不可能实现。
背景:HTML/CSS 文件
所有这一切的基础是代表发票的动态 HTML/CSS 页面。它由页眉区域、列出发票项目的表格和页脚区域组成。页眉和页脚区域的大小相当固定(每个高约 5 厘米);根据发票有多少项目,表格自然会有很大差异。
当发票相当短时,在大多数浏览器中打印(或打印为 PDF)都可以正常工作——整个发票在一页上,看起来很花哨。但是,如果发票越长,事情就会完全崩溃,并且表格会以各种不同的方式被破坏(请参阅下面的“问题”)。
页面上的body
元素是一个控制布局的网格容器,表格位于全角部分。问题末尾的小提琴显示了打印时的结构和损坏的布局。
问题:彻底打破多页表
我认为,在打印多页发票时,我希望发生的行为非常合理且符合预期:
- 表格像往常一样在标题区域之后开始
- 如果需要分页符,则在表格行之间添加分页符
- 表格列标题在每页顶部重复
但这在我目前可用于测试的任何浏览器中似乎都是不可能的。
Firefox出于某种原因,根本拒绝破坏表格,只是在 5 厘米标题区域后将整个页面留空,并将表格放在下一页;如果表格本身对于一页来说太高,它将在稍后添加分页符,但忽略break-inside
设置并在页面边界上将字母切成两半。(它似乎也不想重复表格标题,尽管我在 Google 上找到的大部分内容都表明这应该在 Firefox 中工作。)
Chrome、Opera 和 Brave 等Chromium 浏览器确实支持 Paged Media 和重复的标题行 - 但它们也忽略break-inside
了表格行/单元格(错误声称已修复,但显然没有)并且还在正文行的顶部打印重复的标题行,使输出完全难以辨认。
Safari似乎是唯一真正尊重break-inside
表格内容设置并且只在行之间添加分页符的浏览器——但它根本不支持 CSS Paged Media(原因只有 Apple 开发人员知道),所以你无法控制页面大小,边距等,似乎也没有办法让标题行重复。
那么,我是否在这里遗漏了一些重要的东西,或者真的是在 2021 年,似乎没有主流浏览器能够按照您认为它们应该默认打印的方式打印表格?
有没有一种方法可以打印多页表,只在行之间而不是在行内添加分页符,同时仍然确保在每一页上重复标题行并且不打印覆盖在正文行的顶部?
工作片段
@charset "UTF-8";
@page {
size: A4 portrait;
margin: 15mm
}
body {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
row-gap: 5mm;
align-content: start;
font-family: Arial, Helvetica, sans-serif;
font-size: 10pt;
margin: 0;
padding: 0
}
p {
font-size: inherit
}
section {
grid-column: 1/span all;
height: -webkit-max-content;
height: max-content;
font-size: inherit
}
table {
width: 100%;
border-collapse: collapse;
break-inside: auto
}
table td,
table th {
padding: 1.5mm;
border-bottom: 1px solid #ccc;
border-top: 1px solid #ccc;
vertical-align: top;
font-size: inherit
}
table thead {
background: #faf9fc;
font-weight: 700;
display: table-header-group
}
table th {
text-align: left;
vertical-align: bottom
}
table td,
table th,
table tr {
break-inside: avoid;
break-after: auto
}
.address {
grid-column: span 1;
display: flex;
flex-direction: column
}
.address p {
margin: .5em 0
}
.address p.addressheader {
margin-bottom: 0;
font-style: italic
}
.address span {
margin-right: 1rem
}
.amt {
text-align: right
}
.date {
align-self: start;
grid-column: 2/span 1
}
.invoice-number {
grid-column: span 1
}
.items {
margin: 1cm 0
}
.metadata,
.subtotals {
grid-column: span 2;
padding: 1.5mm;
display: grid;
grid-template-columns: 1fr 2fr
}
.signature {
display: -webkit-box;
display: flex;
justify-content: center;
align-items: center
}
.signature div {
width: 60%;
border-bottom: 1px solid #000;
display: -webkit-box;
display: flex;
align-items: flex-end
}
.signature div p {
min-width: 30%;
margin-bottom: 0;
}
.subtotals {
grid-template-columns: 1fr 1fr;
text-align: right
}
.subtotals > b {
text-align: left
}
.title {
font-size: 24pt;
font-weight: 700;
text-transform: uppercase;
text-align: center;
align-self: center
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sample Invoice</title>
</head>
<body>
<section class="title">Sample invoice</section>
<section class="address to">
<p class="addressheader">Ship to:</p>
<p>
<b>Recipient Name</b><br />
123 Street<br />
12345 City<br />
United States
</p>
<p>Contact Person Name<br />
+1 (555) 123-4567<br />
mail@example.com
</p>
</section>
<section class="address to">
<p class="addressheader">Bill to:</p>
<p>
<b>Customer Name</b><br />
123 Street<br />
12345 City<br />
United States
</p>
<p>Contact Person Name<br />
+1 (555) 123-4567<br />
mail@example.com
</p>
</section>
<section class="address from">
<p class="addressheader">From:</p>
<p>
<b>Company Name</b><br />
123 Street<br />
12345 City<br />
United States
</p>
<p>Contact Person Name<br />
+1 (555) 123-4567<br />
mail@example.com
</p>
</section>
<section class="date">
<b>Invoice Date</b><br />
5 January 2022
</section>
<section class="invoice-number">
<b>Invoice Number</b><br />
999
</section>
<section class="items">
<table>
<thead>
<tr>
<th>HS Code</th>
<th>EAN</th>
<th>Commodity</th>
<th>Origin</th>
<th class="amt">Qty</th>
<th class="amt">Rate</th>
<th class="amt">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
<tr>
<td>12345678</td>
<td>1234567890123</td>
<td>A very useful item</td>
<td>US</td>
<td class="amt">1</td>
<td class="amt">5.00</td>
<td class="amt">5.00</td>
</tr>
</tbody>
</table>
</section>
<section class="metadata">
<b>Tracking number</b><span>1234567890</span>
<b>Transport type</b>DHL Standard
<b>Reference</b>999
<b>Shipment weight (kg)</b>100
<b>Currency</b>USD
<b>Inco terms</b>DDP
<b>Export reason</b>Permanent
<b>Number of colli</b>3
</section>
<section class="subtotals">
<b>Subtotal</b>125.00
<b>Freight costs</b>20.00
<b>Insurance</b>5.00
<b>Other</b>0.00
<b>VAT</b>10.00
<b>Total</b>160.00
</section>
<section class="signature">
<div>
<p>5 Jan 2022</p>
[signature]
</div>
</section>
</body>
</html>