使用 CSS 布局打印具有多列/行的 HTML 表格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26777317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing HTML table with many columns/rows using CSS layout?
提问by Drux
I want to print a large table (so large that its rows are approx. 3 sheets of papers wide) from HTML. If possible, CSS should suffice for layout and the solution should work with different browsers.
我想从 HTML 打印一个大表格(大到它的行大约是 3 张纸宽)。如果可能,CSS 应该足以满足布局,并且该解决方案应该适用于不同的浏览器。
I'm currently defining the following style rules:
我目前正在定义以下样式规则:
table { page-break-inside:auto; }
tr { page-break-inside:auto; }
When I inspect the DOM elements e.g. in Firefox 33.0.2 (on OS X) I can see that the rules are recognized, but then when I look at a print preview ( File| Print| PDF| Open PDF in Preview) all columns that don't fit on the first page are cut off, i.e. I receive 1 page of printed output instead of 3. I have also tried Internet Explorer 11 and 10 to the same effect.
当我检查 DOM 元素时,例如在 Firefox 33.0.2(在 OS X 上)我可以看到规则被识别,但是当我查看打印预览(文件|打印| PDF|在预览中打开 PDF)所有列不适合第一页的内容被截断,即我收到了 1 页而不是 3 页的打印输出。我还尝试了 Internet Explorer 11 和 10 以达到相同的效果。
So how can I layout large HTML tables (ultimately large both in terms of columns an rows) for print out using CSS?
那么如何使用 CSS 布局大型 HTML 表格(在列和行方面都非常大)以便打印出来?
Bonus question: If page-break style components indeed only apply to block-level elements as is indicated in thisprevious answer, would it help if I construct my table from div
s instead of td
s when aiming for print output?
奖金的问题:如果分页式的组件中所表示确实只适用于块级元素此以前的回答,将它的帮助,如果我建我的表从div
!而非td
瞄准打印输出,当s?
UPDATE
更新
Here is a relevant sample that I just tried on JSFiddle. (I don't have an account there, so FWIK I cannot provide a direct link.)
这是我刚刚在 JSFiddle 上尝试的相关示例。(我在那里没有帐户,因此 FWIK 我无法提供直接链接。)
HTML:
HTML:
<body>
<table>
<tr>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_0</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_1</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_2</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_3</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_4</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_5</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_6</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_7</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_8</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_9</td>
</tr>
</table>
</body>
CSS:
CSS:
table { page-break-inside:auto; }
td { border:1px solid lightgray; }
tr { page-break-inside:auto; }
If I try to print this table (e.g. by applying This Frame| Print Frame ...| PDF| Open PDF in Previewto JSFiddle's Resultview in Firefox 33.1 for OS X and for Paper Size/Orientation A4/Portrait) I get one page of output. All columns but the first and part of the second are cut off.
如果我尝试打印此表(例如,通过应用此框架|打印框架 ...| PDF|在预览中打开 PDF到Firefox 33.1 中的JSFiddle 的结果视图,用于 OS X 和纸张尺寸/方向 A4/纵向)我得到一页的输出。除了第一列和第二列的一部分之外的所有列都被切断了。
回答by Josh Burgess
You absolutely need to move away from a table if you need readable vertical printing on the page. Tables are great for display on the page when it's tabular databut are not a viable solution for printing as they don't respect flow.
如果您需要在页面上进行可读的垂直打印,您绝对需要远离桌子。当表格是表格数据时,表格非常适合在页面上显示,但由于不考虑流程,因此不是可行的打印解决方案。
There are plugins (like this one here, no affiliation – just a Google result) that will do this automatically for you, but here's the example. When you use this, make sure that the @media print
is listed appropriately. To test locally, you can change that to @media screen
.
有一些插件(就像这里的这个,没有从属关系——只是一个谷歌结果)会自动为你做这件事,但这里有一个例子。当您使用它时,请确保@media print
正确列出。要在本地进行测试,您可以将其更改为@media screen
.
That won't show the @page
rules listed, but those are visible via a print preview.
这不会显示@page
列出的规则,但可以通过打印预览看到这些规则。
Hope this helps:
希望这可以帮助:
Fiddle for printing in portrait
用于纵向打印的小提琴
HTML
HTML
<section class="table">
<div class="row">
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_0</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_1</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_2</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_3</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_4</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_5</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_6</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_7</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_8</div>
<div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_9</div>
</div>
</section>
CSS
CSS
@media print {
@page {
margin: 2.5cm;
}
div.row > div {
display: inline-block;
border: solid 1px #ccc;
margin: 0.2cm;
}
div.row {
display: block;
}
}
.table {
display: table;
border-spacing: 2px;
}
.row {
display: table-row;
}
.row > div {
display: table-cell;
border: solid 1px #ccc;
padding: 2px;
}
Edit - Printing horizontally across several pages:
编辑 - 跨多页水平打印:
Okay, so this is probably a far less common use case, and we have to do some goofy things with it – so fair warning. I'll try to explain this step-by-step as it's cryptic and obnoxious.
好的,所以这可能是一个不太常见的用例,我们必须用它做一些愚蠢的事情 - 所以公平的警告。我将尝试逐步解释这一点,因为它既神秘又令人讨厌。
Fiddle for printing in landscape here!
小提琴在这里横向打印!
CSS
CSS
@media print {
@page {
margin: 0;
}
body {
height: 100%;
width: 100%;
}
div.row > div {
display: inline-block;
border: solid 1px #ccc;
margin: 0.1cm;
font-size: 1rem;
}
div.row {
display: block;
margin: solid 2px black;
margin: 0.2cm 1cm;
font-size: 0;
white-space: nowrap;
}
.table {
transform: translate(8.5in, -100%) rotate(90deg);
transform-origin: bottom left;
display: block;
}
}
This is the part that matters, as it's setting your print directives. Most of this is stuff we've seen in the original (with some tweaks as I was playing with it).
这是重要的部分,因为它正在设置您的打印指令。其中大部分是我们在原版中看到的东西(在我玩的时候做了一些调整)。
The part we care about comes here:
我们关心的部分来了:
.table {
transform: translate(8.5in, -100%) rotate(90deg);
transform-origin: bottom left;
display: block;
}
What we're doing is flopping the whole thing on its side, and then sliding it to where we expect it to be. translate(8.5in, -100%)
is telling the browser – Slide this element 8.5 inches (the width of a standard letter paper in the US) to the right, and then slide it up 100% of its height (the negative indicates up as opposed to down). We slide it to the right 8.5 inches so that it'll appear at the top of the page when rotated. We slide it up its calculated height so that we don't have an ugly gap to the left of the table when the rotation happens either.
我们正在做的是把整个东西翻到一边,然后把它滑到我们期望的地方。 translate(8.5in, -100%)
告诉浏览器 – 将此元素向右滑动 8.5 英寸(美国标准信纸的宽度),然后将其向上滑动 100% 的高度(负数表示向上而不是向下)。我们将其向右滑动 8.5 英寸,以便在旋转时它会出现在页面顶部。我们将它向上滑动到它的计算高度,这样当旋转发生时我们也不会在桌子的左边有一个难看的间隙。
Then, we instruct it that we want all of those calculations run in relation to the bottom left
of the element's normal position in document flow. This keeps this crazy long table from being rotated way off to the right by setting the left
property. The bottom
property is important because we're rotating it clockwise a quarter turn, and if we did that from the top, it would be off the page to the left. That quarter turn is described in the next part of the transform
statement: rotate(90deg)
;
然后,我们指示它我们希望所有这些计算都相对于bottom left
元素在文档流中的正常位置运行。通过设置left
属性,这可以防止这个疯狂的长桌子向右旋转。该bottom
属性很重要,因为我们将它顺时针旋转四分之一圈,如果我们从顶部旋转,它会离开页面左侧。这季又在下一部分中描述transform
语句:rotate(90deg)
;
Voila. The thing prints across multiple pages.
瞧。东西打印在多页上。
Before you ask: No. There is no way to prevent the page break inside the element of which I'm aware. I know it's obnoxious, ugly and all that garbage, but we can only work with the tools which we're given.
在你问之前:不。没有办法阻止我知道的元素内的分页符。我知道它令人讨厌、丑陋和所有垃圾,但我们只能使用我们提供的工具。
Update Firefox confirmed working: 
更新 Firefox 确认有效: 
回答by RoToRa
page-break-inside: auto;
is the default style, so unless you have a rule setting them differently, those rules will do nothing.
page-break-inside: auto;
是默认样式,因此除非您有不同的规则设置它们,否则这些规则将不起作用。
If your table isn't being broken onto multiple pages, then it's most likely because there some other rule you added, which prevents it - my guess an overflow: hidden
.
如果您的表格没有被分成多个页面,那么很可能是因为您添加了一些其他规则,这会阻止它 - 我猜是overflow: hidden
.
What you first should do is remove allstyles, and see if that prints on multiple pages. If yes, start adding your styles back (rule by rule, or if necessary line by line) to find the problem.
您首先应该做的是删除所有样式,然后查看是否在多个页面上打印。如果是,请开始添加您的样式(按规则或在必要时逐行添加)以查找问题。
回答by Pipo
If you want to force page break you should use page-break-beforeor page-break-after. You need to know that the styled element should contain a non-empty block-level element and that it can't be absolutely positioned. However it is quite inconsistent on tables elements. Which leads us to your last question : yes, it would be more consistent to build your tables with divs
.
如果你想强制分页,你应该使用page-break-before或page-break-after。你需要知道样式元素应该包含一个非空的块级元素并且它不能被绝对定位。然而,它在表格元素上非常不一致。这将我们引向您的最后一个问题:是的,使用divs
.
However, considering what you want to achieve (printing large horizontal tables) you should know that trying to fit 3 pages into 1 can't work as your content won't be readable. As a matter of fact, the only best practice would be to use a vertical layout instead(just for print or for both web and print).
但是,考虑到您想要实现的目标(打印大型水平表格),您应该知道尝试将 3 页放入 1 页是行不通的,因为您的内容将不可读。事实上,唯一的最佳做法是改用垂直布局(仅用于打印或同时用于 Web 和打印)。