【问题标题】:How to deal with page breaks when printing a large HTML table打印大型 HTML 表格时如何处理分页符
【发布时间】:2010-12-18 07:56:07
【问题描述】:

我有一个项目需要打印一个多行的 HTML 表格。

我的问题是表格打印在多页上的方式。它有时会将一行切成两半,使其无法阅读,因为其中一半位于页面的边缘,而其余部分则打印在下一页的顶部。

我能想到的唯一可行的解​​决方案是使用堆叠的 DIV 而不是表格,并在需要时强制分页。但在完成整个更改之前,我想我可以先在这里问一下。

【问题讨论】:

  • 在切线上,可能值得使用以下 css thead {display: table-header-group; }<thead> 添加到您的表中,以便在所有后续页面上打印表头(对于 loooooong 数据表很有用) .

标签: html css printing html-table


【解决方案1】:

使用这些 CSS 属性:

page-break-after

page-break-before 

例如:

<html>
<head>
<style>
@media print
{
table {page-break-after:always}
}
</style>
</head>

<body>
....
</body>
</html>

via

【讨论】:

  • 我不确定,你必须检查一下。如果不是,则拆分为不同的数组,并用空 div 分隔数组
  • 我认为您必须将其应用于表格行甚至单元格,但不能应用于表格。除此之外,它应该可以工作。
  • 在 chrome 中不起作用。当应用于 TR 时,就像 2012 年 6 月 13 日一样被忽略
【解决方案2】:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<style type="text/css">
    table { page-break-inside:auto }
    tr    { page-break-inside:avoid; page-break-after:auto }
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tbody>
        <tr>
            <td>x</td>
        </tr>
        <tr>
            <td>x</td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

【讨论】:

  • 这在 WebKit 浏览器(例如 Safari 和 Chrome)中也会失败
  • 虽然这是符合标准的方法,但目前唯一实现该标准的浏览器是 Opera。请注意,这是 css2 的一部分,因此在未来一段时间内,缺乏实现可能会成为一个问题,因为显然没人关心。
  • CSS 2.1 规范表明分页符样式属性仅适用于块级元素。表格行的默认显示模式是表格行。不幸的是,默认情况下没有表元素是块级元素,包括表本身。
  • @SinanÜnür 这不是一个要求,所以你不能依赖它,不幸的是,从我的测试中我可以看到 webkit 看到了“可能”并忽略了它之外的任何东西。奇怪的是,IE 有一些相当不错的大表格打印支持。从没想过我会在任何给定点上歌颂它。
  • 我可以确认这在 Chrome 或任何其他 Webkit 浏览器(例如 Safari、Opera)中不能正常工作——除非“工作正常”是指“排除任何被认为是可选的功能” .我认为大多数人想要的是运行页眉和页脚,以及只允许行之间分页符的表格,截至 2015 年 11 月 13 日,这两者都没有在 Webkit 中实现。
【解决方案3】:

注意:当标签使用 page-break-after:always 时,它会在表格的最后一位之后创建一个分页符,每次最后都会创建一个完全空白的页面! 要解决此问题,只需将其更改为 page-break-after:auto。 它将正确中断并且不会创建额外的空白页。

<html>
<head>
<style>
@media print
{
  table { page-break-after:auto }
  tr    { page-break-inside:avoid; page-break-after:auto }
  td    { page-break-inside:avoid; page-break-after:auto }
  thead { display:table-header-group }
  tfoot { display:table-footer-group }
}
</style>
</head>

<body>
....
</body>
</html>

【讨论】:

  • 在 Chrome 上为我工作,是一个不错的纯 CSS 解决方案。
  • 我正在尝试相同的解决方案,但它不会破坏表格数据并消失额外数据,而不是在下一页上显示它。有什么猜测吗?
  • 也为我工作,是我动态填充表格解决方案的优雅解决方案。
【解决方案4】:

从思南Ünür解决方案扩展:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<style type="text/css">
    table { page-break-inside:auto }
    div   { page-break-inside:avoid; } /* This is the key */
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tr>
            <td><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <tr>
            <td><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

似乎page-break-inside:avoid在某些浏览器中只考虑块元素,而不考虑单元格、表格、行和内联块。

如果您尝试display:block TR 标记,并在那里使用page-break-inside:avoid,它可以工作,但会弄乱您的表格布局。

【讨论】:

  • 这是一种使用 jquery 动态添加 div 的简单方法:$(document).ready(function(){$("table tbody th, table tbody td").wrapInner("&lt;div&gt;&lt;/div&gt;");});
  • 感谢 sinan ürün、vicenteherrera 和 Chrisbloom7。我应用了您的答案组合,现在可以使用了!
  • 您可以尝试将@media CSS 设置为tr { display: block; } 用于仅打印,而不是添加所有无关的&lt;div&gt; 元素。 (尚未测试但值得一看)
【解决方案5】:

这里的答案在 Chrome 中都不适合我。 GitHub 上的 Averin 创建了 some useful Javascript for this purpose,这对我有用:

只需将 js 添加到您的代码中并将“splitForPrint”类添加到您的表格中,它就会将表格整齐地拆分为多个页面并将表格标题添加到每个页面。

【讨论】:

  • 你有关于如何应用这个的示例吗?我一直在尝试将我的表类名分配为splitForPrint,但在 JS 中,没有任何地方使用类名splitForPrint 引用元素。只有var splitClassName = 'splitForPrint'; 的部分,仅此而已。
  • 投了反对票,因为您链接到的脚本在没有大量挑选和重新配置的情况下无法解决 OP 的问题,而且您没有提供任何示例来说明如何去做。
  • 对我来说就像一个魅力,其他解决方案都不起作用。 +1 必须添加一点 css 才能获得正确的中断 .page-break { page-break-after: always; }
  • 是的,通过添加 .page-break { page-break-after: always; } 它拯救了我的一天!
【解决方案6】:

接受的答案不适用于所有浏览器,但以下 css 确实对我有用:

tr    
{ 
  display: table-row-group;
  page-break-inside:avoid; 
  page-break-after:auto;
}

html结构是:

<table>
  <thead>
    <tr></tr>
  </thead>
  <tbody>
    <tr></tr>
    <tr></tr>
    ...
  </tbody>
</table>

就我而言,thead tr 还存在一些其他问题,但这解决了保持表行不中断的原始问题。

由于标题问题,我最终得到了:

#theTable td *
{
  page-break-inside:avoid;
}

这并不能防止行中断;只是每个单元格的内容。

【讨论】:

    【解决方案7】:

    我最近用一个很好的解决方案解决了这个问题。

    CSS

    .avoidBreak { 
        border: 2px solid;
        page-break-inside:avoid;
    }
    

    JS

    function Print(){
        $(".tableToPrint td, .tableToPrint th").each(function(){ $(this).css("width",  $(this).width() + "px")  });
        $(".tableToPrint tr").wrap("<div class='avoidBreak'></div>");
        window.print();
    }
    

    像魅力一样工作!

    【讨论】:

      【解决方案8】:

      我检查了许多解决方案,但没有一个运行良好。

      所以我尝试了一个小技巧,它奏效了:

      tfoot 风格:position: fixed; bottom: 0px; 放置在最后一页的底部,但如果页脚太高,则会与表格内容重叠。

      tfoot 只有:display: table-footer-group; 不重叠,但不在最后一页的底部...

      让我们放两个tfoot:

      TFOOT.placer {
        display: table-footer-group;
        height: 130px;
      }
      
      TFOOT.contenter {
        display: table-footer-group;
        position: fixed;
        bottom: 0px;	
        height: 130px;
      }
      <TFOOT  class='placer'> 
        <TR>
          <TD>
            <!--  empty here
      -->
          </TD>
        </TR>
      </TFOOT>	
      <TFOOT  class='contenter'> 
        <TR>
          <TD>
            your long text or high image here
          </TD>
        </TR>
      </TFOOT>

      一个在非最后一页保留位置,第二个放在您的实际页脚中。

      【讨论】:

        【解决方案9】:

        我最终遵循了@vicenteherrera 的方法,并进行了一些调整(可能是特定于引导程序 3 的)。

        基本上;我们不能破坏trs 或tds,因为它们不是块级元素。所以我们将divs 嵌入到每个中,并将我们的page-break-* 规则应用于div。其次;我们在每个 div 的顶部添加一些填充,以补偿任何样式伪影。

        <style>
            @media print {
                /* avoid cutting tr's in half */
                th div, td div {
                    margin-top:-8px;
                    padding-top:8px;
                    page-break-inside:avoid;
                }
            }
        </style>
        <script>
            $(document).ready(function(){
                // Wrap each tr and td's content within a div
                // (todo: add logic so we only do this when printing)
                $("table tbody th, table tbody td").wrapInner("<div></div>");
            })
        </script>
        

        margin 和 padding 调整对于抵消引入的某种抖动是必要的(根据我的猜测 - 来自引导程序)。我不确定我是否会从这个问题的其他答案中提出任何新的解决方案,但我认为这可能会对某人有所帮助。

        【讨论】:

          【解决方案10】:

          我已经尝试了上面给出的所有建议,并为这个问题找到了简单且有效的跨浏览器解决方案。此解决方案不需要样式或分页符。对于解决方案,表格的格式应为:

          <table>
              <thead>  <!-- there should be <thead> tag-->
                  <td>Heading</td> <!--//inside <thead> should be <td> it should not be <th>-->
              </thead>
              <tbody><!---<tbody>also must-->
                  <tr>
                      <td>data</td>
                  </tr>
                  <!--100 more rows-->
              </tbody>
          </table>
          

          以上格式测试并在跨浏览器中工作

          【讨论】:

            【解决方案11】:

            伙计们...这里的大多数解决方案都不起作用。所以这就是我的工作方式..

            HTML

            <table>
              <thead>
               <tr>
                 <th style="border:none;height:26px;"></th>
                 <th style="border:none;height:26px;"></th>
                 .
                 .
               </tr>
               <tr>
                 <th style="border:1px solid black">ABC</th>
                 <th style="border:1px solid black">ABC</th>
                 .
                 .
               <tr>
              </thead>
            <tbody>
            
                //YOUR CODE
            
            </tbody>
            </table>
            

            第一组头部用作虚拟头部,这样在分页时第二个头部(即原始头部)不会缺少顶部边框。

            【讨论】:

              【解决方案12】:

              我遇到了同样的问题并到处寻找解决方案,最后,我找到了适用于每个浏览器的东西。

              html {
              height: 0;
              }
              

              使用这个 css 或代替 css 你可以有这个 javascript

              $("html").height(0);
              

              希望这对你也有用。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-07-05
                • 1970-01-01
                • 2018-05-12
                • 2014-03-24
                • 2014-02-11
                相关资源
                最近更新 更多