使用CSS布局打印包含许多列/行的HTML表格?

时间:2014-11-06 10:38:12

标签: html css layout printing internet-explorer-10

我想从HTML打印一张大表(大到大约3张纸宽)。如果可能,CSS应该足够布局,解决方案应该适用于不同的浏览器。

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

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

当我检查DOM元素时,例如在Firefox 33.0.2中(在OS X上)我可以看到规则被识别,但是当我查看打印预览时(文件 | 打印 | PDF | 在预览中打开PDF )所有不适合第一页的列都被截断,即我收到1页打印输出而不是3页。我也有尝试使用Internet Explorer 11和10来达到同样的效果。

那么如何使用CSS打印出大型HTML表格(最终在列数和行数方面都很大)?

奖金问题:如果分页符样式组件确实仅适用于this上一个答案中指示的块级元素,那么如果我从div s而不是{td构建我的表格会有所帮助{1}}当瞄准打印输出时?

更新

以下是我刚刚在JSFiddle上尝试过的相关示例。 (我在那里没有帐户,所以FWIK我无法提供直接链接。)

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

如果我尝试打印此表格(例如,通过应用此框架 | 打印框架... | PDF | 打开预览中的PDF 到Firefox 33.1 for OS X中的JSFiddle 结果视图以及纸张大小/方向A4 /纵向)我得到一页输出。除第一部分和第二部分之外的所有列都被截断。

3 个答案:

答案 0 :(得分:23)

如果您需要在页面上进行可读垂直打印,则绝对需要离开桌子。表格非常适合在表格数据页面上显示,但由于它们不尊重流量,因此不适合打印。

有些插件(如this one here, no affiliation – just a Google result)会自动为您执行此操作,但这是示例。使用此功能时,请确保正确列出@media print。要在本地进行测试,您可以将其更改为@media screen

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

希望这会有所帮助:

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

编辑 - 跨多个页面水平打印:

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

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

这是重要的部分,因为它正在设置您的打印指令。大部分都是我们在原版中看到的东西(我正在玩它时会有一些调整)。

我们关心的部分来到这里:

 .table {
     transform: translate(8.5in, -100%) rotate(90deg);
     transform-origin: bottom left;
     display: block;
 }

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

然后,我们指示我们希望所有这些计算都与文档流中元素正常位置的bottom left相关联。通过设置left属性,可以防止这个疯狂的长桌旋转到右边。 bottom属性非常重要,因为我们将它顺时针旋转四分之一圈,如果我们从顶部开始旋转,它将离开页面左侧。该季度回合在transform声明的下一部分中进行了描述:rotate(90deg);

瞧。东西打印在多个页面上。

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

更新Firefox确认工作:Firefox 33.1 on Mac

答案 1 :(得分:8)

page-break-inside: auto;是默认样式,因此,除非您的规则设置不同,否则这些规则将不执行任何操作。

如果您的表格没有被分成多个页面,那么它很可能是因为您添加了一些其他规则,这会阻止它 - 我的猜测是overflow: hidden

您首先应该删除所有样式,并查看是否在多个页面上打印。如果是,请开始添加样式(按规则排序,或者必要时逐行添加)以查找问题。

答案 2 :(得分:2)

如果您想强制分页,请使用 page-break-before page-break-after 。您需要知道样式元素应该包含非空块级元素,并且它不能绝对定位。但是它在表元素上非常不一致。这导致我们回答您的上一个问题:是的,使用divs构建表格会更加一致。

然而,考虑到你想要实现的目标(打印大型水平表),你应该知道,尝试将3个页面放入1可以起作用,因为你的内容不会被读取。 事实上,唯一的最佳做法是使用垂直布局(仅用于打印或用于网页和打印)。