使用 CSS 布局打印具有多列/行的 HTML 表格? [英] Printing HTML table with many columns/rows using CSS layout?

查看:29
本文介绍了使用 CSS 布局打印具有多列/行的 HTML 表格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从 HTML 打印一个大表格(大到它的行大约有 3 张纸宽).如果可能,CSS 应该足以满足布局,并且解决方案应该适用于不同的浏览器.

我目前正在定义以下样式规则:

table { page-break-inside:auto;}tr { page-break-inside:auto;}

当我检查 DOM 元素时,例如在 Firefox 33.0.2(在 OS X 上)我可以看到规则被识别,但是当我查看打印预览时( File | Print | PDF | 在预览中打开 PDF) 所有不适合第一页的列都被切断,即我收到 1 页打印输出而不是 3 页.我也尝试过 InternetExplorer 11 和 10 效果相同.

那么如何使用 CSS 来布置大型 HTML 表格(最终在列和行方面都很大)以进行打印?

额外问题:如果分页样式组件确实仅适用于块级元素,如this中所示回答,如果我在针对打印输出时从 divs 而不是 tds 构建我的表格会有帮助吗?

更新

这是我刚刚在 JSFiddle 上尝试的相关示例.(我在那里没有帐户,因此 FWIK 我无法提供直接链接.)

HTML:

<表格><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>

CSS:

table { page-break-inside:auto;}td { 边框:1px 纯浅灰色;}tr { page-break-inside:auto;}

如果我尝试打印此表格(例如通过应用This Frame | Print Frame ... | PDF | OpenPDF 预览 到 JSFiddle 在 Firefox 33.1 中的 Result 视图(OS X 和纸张尺寸/方向 A4/纵向)我得到一页输出.除第一列和第二列的一部分外,所有列都被截断.

解决方案

如果您需要在页面上进行可读的垂直打印,您绝对需要远离表格.表格非常适合在页面上显示当它是表格数据时,但不是一种可行的打印解决方案,因为它们不尊重流程.

有插件(比如这里有这个,没有从属关系——只是一个谷歌结果)这将自动为您执行此操作,但这是示例.当您使用它时,请确保 @media print 被适当地列出.要在本地进行测试,您可以将其更改为 @media screen.

这不会显示列出的 @page 规则,但可以通过打印预览看到这些规则.

希望这有帮助:

用于纵向打印的小提琴

HTML

<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>

</节>

CSS

@media 打印 {@页 {边距:2.5cm;}div.row >div {显示:内联块;边框:实心 1px #ccc;边距:0.2cm;}div.row {显示:块;}}.桌子 {显示:表;边框间距:2px;}.排 {显示:表格行;}.row >div {显示:表格单元格;边框:实心 1px #ccc;填充:2px;}

编辑 - 跨多页水平打印:

好的,所以这可能是一个不太常见的用例,我们必须用它做一些愚蠢的事情 - 所以公平的警告.我将尝试逐步解释这一点,因为它既神秘又令人讨厌.

此处用于横向打印的小提琴!

CSS

@media 打印 {@页 {边距:0;}身体 {高度:100%;宽度:100%;}div.row >div {显示:内联块;边框:实心 1px #ccc;边距:0.1cm;字体大小:1rem;}div.row {显示:块;边距:实心 2px 黑色;边距:0.2cm×1cm;字体大小:0;空白:nowrap;}.桌子 {变换:平移(8.5 英寸,-100%)旋转(90 度);变换原点:左下角;显示:块;}}

这是重要的部分,因为它正在设置您的打印指令.大部分内容都是我们在原版中看到的内容(在我玩的时候做了一些调整).

我们关心的部分来了:

 .table {变换:平移(8.5 英寸,-100%)旋转(90 度);变换原点:左下角;显示:块;}

我们正在做的是将整个东西翻到一边,然后将其滑到我们期望的位置.translate(8.5in, -100%) 是在告诉浏览器 – 将此元素向右滑动 8.5 英寸(美国标准信纸的宽度),然后将其向上滑动 100%它的高度(负数表示向上而不是向下).我们将其向右滑动 8.5 英寸,以便在旋转时它会出现在页面顶部.我们将它向上滑动到其计算出的高度,这样在旋转发生时我们也不会在桌子的左侧有一个难看的间隙.

然后,我们指示它我们希望所有这些计算都相对于元素在文档流中的正常位置的左下运行.通过设置 left 属性,这可以防止这个疯狂的长表向右旋转.bottom 属性很重要,因为我们将它顺时针旋转四分之一圈,如果我们从顶部旋转,它将离开页面左侧.transform 语句的下一部分描述了那个四分之一转:rotate(90deg);

瞧.东西打印在多页上.

在你提问之前:不.没有办法阻止我知道的元素内的分页符.我知道它令人讨厌、丑陋和所有垃圾,但我们只能使用我们提供的工具.

更新 Firefox 确认有效:

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.

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.

So how can I layout large HTML tables (ultimately large both in terms of columns an rows) for print out using CSS?

Bonus question: If page-break style components indeed only apply to block-level elements as is indicated in this previous answer, would it help if I construct my table from divs instead of tds when aiming for print output?

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.)

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:

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 Preview to JSFiddle's Result view 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.

解决方案

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 data but 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.

That won't show the @page rules listed, but those are visible via a print preview.

Hope this helps:

Fiddle for printing in portrait

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

@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

@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.

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);

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:

这篇关于使用 CSS 布局打印具有多列/行的 HTML 表格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆