如何打印HTML页面的页眉和页脚

3
我尝试为HTML打印页面中的每个页面添加页眉和页脚。我编写了下面的代码。
@page {
  @top-left {
    content: "this is the page header";
  }
}

@page: right {
  @bottom-right {
    content: counter(page) "page";
  }
}

它无法正常工作。我认为最近的CSS更新中删除了@bottom-right、@bottom-left等功能。这些元素没有显示任何内容。我已经尝试了以下代码。

<style>
@media print {
  .page-header {
    position: fixed;
    top: 0;
    right: 0;
  }

  .page-footer {
    position: fixed;
    bottom: 0;
    right: 0;
  }
}
</style>
<section class='print-me'>
   <div class='row'>
      <div col='6'>..... dynamically generated text, graphs and images about 30 pages long which are difficult to handle manually ....</div>
   </div>
</section>

 <!-- I need this page header and footer in every page -->
 <h5 class="page-header">..... copyright and logo ...../h5>
 <h5 class="page-footer">..... page number: .....</h5>
 <!-- I want to generate page number dynamically -->

由于我有大约30页HTML内容,其中有非常长的段落是动态生成的,如果我尝试第二种方法,它将与页眉和页脚重叠。

编辑我在 medium 上找到了这篇文章。这有助于我以某种方式生成页眉和页脚。但是,此技术还会破坏报表内的表格。此外,缺少页面编号生成部分?


这个回答解决了你的问题吗?如何使用HTML在每个打印页面上打印文档的页眉和页脚? - Heretic Monkey
1个回答

2

这里有一些从我尚未发布的项目中提取出来的技巧,用于生成简历...

/* Thanks be to: https://dev59.com/2WIk5IYBdhLWcg3wDKJb#25880258
   And may allow for repeated headers only in print preview
 */
div[class*="resume-section-experience-"] {
  display: table;
  width: 100%
}
div[class*="resume-section-experience-"] > div {
  display: table-cell;
  overflow: hidden;
}

/* Add further section repetition hiding here */
.resume-section-experience-professional ~ .resume-section-experience-professional > div:before {
  content: "";
  display: block;
  margin-bottom: -3em; // inverse of header height
}
.resume-section-experience-volunteer ~ .resume-section-experience-volunteer > div:before {
  content: "";
  display: block;
  margin-bottom: -3em; /* inverse of header height */
}

.resume-headings {
  height: 3em;
}
div[class*="resume-section-experience-"] > div > div {
  display: inline-block;
  width: 100%;
  vertical-align: top;
}


/**
 * Attempt to keep section headings from displaying at the bottom of pages
 * and discourage page brakes within various content blocks.
 */
@media print {
  h2, h3, h4, ul, .professional-experience {
    page-break-after: avoid;
  }

  pre, blockquote, ul, div[class*="-training"], div[class*="-requirements"], div[class*="-experience"], div[class*="-skills"], div[class*="resume-section-experience-"] {
    page-break-inside: avoid;
  }
}

如果你想要调整目标元素的名称/类名,并且可能需要在段落之间调整间距,但以上代码可以满足相似的要求。

尽管如此,如果你知道段落将在某些时候分页,那么缩小容器的可用高度,以便有空间放置固定定位的页眉和页脚,可能会更好。

如果您编辑问题以包括一些标记(并通知我),我将尝试再次进行编辑,以更好地解决您特定的用例。

关于上述CSS的另一个注意事项; 对于我的用例,我发现重复页眉/页脚数据,然后在不在页面顶部/底部时选择性地隐藏它们更容易在Web和打印视图之间进行格式化。


@dhiraj ...主要问题是如何生成页码

如果页码是主要问题,那么应该可以利用 CSS 的计数器技巧来实现 (删除了“display: table”,“display: table-footer-group”)

print.css

/**
 * print modifications **must** be within a style sheet
 */
@media print {
  /*
   * Note, forced page breaks are only for testing when content is insufficient
   */
  .page_content__print_break {
    page-break-after: always;
    break-after: always;
  }

  footer.footer_content {
    visibility: show;
    opacity: 1;
    filter: alpha(opacity=100);

    position: fixed;
    bottom: 0;
  }

  footer.footer_content::after {
    counter-increment: page_number;
    content: "Page:" counter(page_number);
  }
}

index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Table based CSS footer example</title>

    <style media="screen">
      footer.footer_content,
      .page_content__print_break {
        visibility: hidden;
        opacity: 0;
        filter: alpha(opacity=0);
      }
    </style>

    <link rel="stylesheet" href="print.css">
  </head>


  <body>
    <section class="page_content">
      <div class="page_content__row">
        <p>This is where page content should be placed</p>
        <p>
          Thanks be to:
           <a href="https://dev59.com/3mIj5IYBdhLWcg3wn2do">
             Print page numbers on pages when printing html
          </a>
        </p>
      </div>

      <!--
        Note, following element is only for this example and should
        be removed for the use-case of this posted quesiton.
      -->
      <div class="page_content__print_break"></div>

      <div class="page_content__row">
        <p>
          More example content to perhaps force a second page to be printed...
        </p>

        <p>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat. Duis aute irure dolor in
          reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
          pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
          culpa qui officia deserunt mollit anim id est laborum.
        </p>
      </div>

    </section>


    <footer class="footer_content" role="contentinfo"></footer>
  </body>
</html>

顺便提一下,通过查看上面内部链接的问答,我发现您在当前问题中使用的@page可能不被CSS完全支持,要获得更多的“花哨效果”,需要使用PagedJS。另外,请查看官方CSS文档以获取支持的@page功能。
...然而,经过一些测试,似乎浏览器的支持在近年来已经发生了变化;Firefox和Chrome似乎在打印时不执行counter操作,而page-break-*已经改为break-*,尽管这个属性现在似乎被两个浏览器忽略了 :-|
编辑:根据@contm的评论,链接样式表与元素中的样式可能会产生不同的结果 X-\
实际上,在查看Mozilla关于break-after兼容性图表后,该功能已被Internet Explorer支持。
如果我找到任何解决这些问题的方法,我一定会再次编辑此答案。
更新:
根据CSS规范,@page目前仍处于WIP(草案或工作进展)阶段,因此截至2020年,不应期望任何供应商实施该规范。
固定而不是重复的页脚仅会计算一次,在所有增量完成后;以下是一个示例,每页都将报告Page: 2,因为有两个page_content__row...

print.css

@media print {
  :root {
    counter-reset: page_count;
  }

  .page_content__row {
    counter-increment: page_count;
  }

  .page_content__print_break {
    page-break-after: always;
    break-after: always;
  }

  footer.footer_content {
    visibility: show;
    opacity: 1;
    filter: alpha(opacity=100);

    position: fixed;
    bottom: 0;
  }

  footer.footer_content::after {
    content: "Page: " counter(page_count);
  }
}

除了第三方库外,我能想到的唯一自定义页脚信息的选项是在动态生成内容时计算页面断点,然后在需要的地方插入页脚元素。当然,这有一个巨大的缺点,即客户端字体/缩放设置将破坏页脚自定义或必须被忽略,如果您选择这条路,可能更简单的方法是在服务器端生成PDF文档并提供下载链接。


谢谢您的回答。我已经更新了我的问题。可以帮忙吗?主要问题是如何生成页码。 - dhiraj
1
当然欢迎你,@dhiraj!在更清晰的异常处理上,我对这个答案进行了一些补充,希望能让你更接近成功。如果还有问题,请随时联系我,我会花更多时间与你一起研究解决方案。 - S0AndS0
1
感谢您的支持。除了一个问题,我已经解决了所有的事情,即“页码”。由于内容是动态的,我无法为每一页设置“page_content__print_break”并计算页码。此外,我的生成报告根据用户选择有15-30页大小。我尝试使用“pagedjs”,但仍然存在许多CSS错误。您有关于页码的好主意吗? - dhiraj
1
page_content__print_break的内容可以根据您的用例删除;它在示例代码中是为了确保打印预览中有多个页面。我对PagedJS一无所知,只是因为其他人曾经声称它响应@page属性,就像PrinceXML一样,如果互联网是可信的... 当我在我的端上挑剔时,CSS规范的第4节关于自动编号可能值得一读; 特别是作用域限制。 - S0AndS0
1
另外,@page 规范说明该属性是一个草案(正在进行的工作),因此不应使用/引用。换句话说,@page 是未来功能的 _梦想_,目前我们不能期望任何供应商实现它... 经过更多测试后,看起来纯 CSS 将 无法 正确地增加页面计数而不重复页脚元素,因为固定页脚只被计算/增加一次。但如果内容生成能够计算并添加隐藏的页脚,那可能仍然可以工作。 - S0AndS0
是的,没错。但由于报告是动态生成的,我无法添加隐藏页脚。仍在寻找页面编号。 - dhiraj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接