【问题标题】:How to print the header and footer of the HTML page如何打印 HTML 页面的页眉和页脚
【发布时间】:2020-07-29 07:41:42
【问题描述】:

我尝试在每个页面中为 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 内容,其中有很长的段落是动态生成的,如果我尝试第二种方法,它将与页眉和页脚重叠。

编辑I found this article on medium。这有助于我以某种方式生成页眉和页脚。但是这种技术也破坏了我在报告中的表格。也缺少页码生成部分?

【问题讨论】:

标签: html css media


【解决方案1】:

以下是从我尚未发布的用于生成简历的项目中提取的一些技巧...

/* Thanks be to: https://stackoverflow.com/questions/19646835/print-repeating-page-headers-in-chrome/25880258#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 ...主要问题是如何生成页码

如果页码是主要关注点,那么应该可以利用 display: tabledisplay: table-footer-group CSS 的反技巧...

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://stackoverflow.com/questions/20050939">
             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 的评论指出,在 head 元素中链接样式表与样式可能会产生不同的结果 X-\

实际上查看Mozilla's developer documentation on break-after兼容性图表后,Internet Exporter支持此功能

如果我找到任何可以解决这些问题的方法,我一定会再次对此答案进行修改。


更新;

根据 CSS 规范。对于@page,它目前是一个 WIP(草案或正在进行的工作),因此到 2020 年,预计没有供应商会实施。

fixed 而不是重复的页脚只计算一次,并且在所有增量完成之后;将在每个页面上报告 Page: 2 的示例,因为有两个 page_content__rows...

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!除了更明确的例外,我对这个答案做了一些补充,这可能会使成功更接近。如果没有,请随时再次联系我,我一定会花更多时间与您一起研究解决方案。
  • 感谢您的支持。我弄清楚除了一件事之外的一切,即page number。由于内容是动态的,我无法将page_content__print_break 设置为每一页并计算页码。此外,根据用户选择,我生成的报告大小为 15-30 页。我试过pagedjs,它仍然有很多CSS错误。你对页码有什么好的想法吗?
  • page_content__print_break 可以为您的用例删除东西;它在示例代码中以确保打印预览中有多个页面。我对PagedJS一无所知,它被包括在内只是因为其他人说它响应@page属性,PrinceXML也是如此;如果要相信互联网...虽然我在这结束时 pick,但 CSS 规范的第 4 节。在auto-numbering 上可能值得回顾;特别是范围限制。
  • 还有@page 规范。声明该属性是一个草稿(正在进行的工作),因此不应使用/引用它。或者换句话说,@page 是未来功能的梦想,目前我们不能指望任何供应商实现它......经过更多测试,它看起来像纯 CSS 将 不能在不重复页脚元素的情况下正确增加页数,因为固定页脚只计算/增加一次。但是,如果内容生成能够计算和添加可能仍然有效的隐藏页脚。
猜你喜欢
  • 1970-01-01
  • 2013-09-18
  • 2011-06-20
  • 2014-06-02
  • 2011-11-01
  • 2021-01-18
  • 2012-04-15
  • 2020-01-02
  • 2013-12-01
相关资源
最近更新 更多