【问题标题】:How can I count CSS page breaks for printed HTML?如何计算打印 HTML 的 CSS 分页符?
【发布时间】:2011-06-06 17:37:46
【问题描述】:

我正在使用 HTML 生成报告,我正在使用 CSS 来控制使用 page-break-after 等的分页。我为用户提供了一次打印多个报告的选项,我将这些报告创建为单个报告的部分动态生成的 HTML 文档。使其成为单个文档可以使其成为单个打印作业,以避免打印假脱机问题。

我的问题是:我想以“第 x 页,共 n 页”的格式对较大动态 HTML 的一部分的页面进行编号。但是,如果我让打印机这样做,它会(正确地)将文档视为单个文档并对整个文档进行编号。

有什么方法可以确定 CSS 分页符何时会发生,所以我可以在打印之前将它们计算为一个部分,并为长单中的部分添加我自己的编号(例如 HTML 元素)文件?

似乎应该有办法让我做到这一点,但在过去的几天里,我没有找到解决方案,所以我想我会 ping Stackoverflow。

更新:我最终做了什么:

我接受了克里斯托弗的回答,因为虽然我没有完全使用它,但它为我指明了正确的方向。

我最终使用 jQuery 对内容进行了计算,基于打印到的纸张大小、边距、字体大小等,然后添加具有用于分页的 CSS 的分页符元素。我跟踪添加了多少分页符 div,然后在处理完所有内容后更新每个分页符 div 中的 html“page x of n”信息。这让我不必知道一开始会有多少页(感谢 jQuery .each)。

显然这个解决方案存在一些问题:

  1. “第 x 页,共 n 页”元素不会显示为真正的页脚,而是显示在每页内容的底部。在我的情况下,这是一个可以接受的妥协。

  2. 拆分本身比页面大的​​内容元素,特别是考虑到大部分内容是由 php 生成的,有点复杂。我让它工作了,但同样,它需要的假设可能会因打印变化而中断。

  3. 计算取决于有关打印纸张大小、边距、字体大小等的假设。在我在 Intranet 上运行的情况下,这又是一个可以接受的折衷方案,因为我可以控制这些选项。可以添加额外的代码来处理未来的一些变化(例如纸张大小)。

这个解决方案虽然不完美而且有点“脆弱”,但解决了我的问题,允许我一次打印多个报告,避免打印机假脱机超时,跟踪并重新启动页码,并避免生成 PDF 作为中间步骤打印。

我发现这是一个非常难以破解的难题,因此我仍然希望对解决方案提出意见和意见。

谢谢!

更新 2:最终解决方案...避免自己的头痛:

虽然我使用这种方法可能比我应该做的更远,并取得了一些小成功,但最终解决方案确实不是一个,因为它最终变得太“脆弱”而无法更改。报告格式的任何更改、添加到现有报告中的新内容、纸张大小等都会破坏计算,并最终导致大量额外的工作!

那么,最终的解决方案是什么? “抵抗是徒劳的!”只需将报告制作为 PDF 格式。如果你愿意,你可以开始“我们告诉过你”的合唱,我可以接受 ;-)

我选择了 TCPDF 库,它非常棒,如果开始有点困难的话。这些例子非常有帮助。现在我对报告进行了完全的自定义,一切都按原样生成。多个报告很容易创建为单个 PDF(防止打印假脱机问题),其页面组允许编号完全按照我的需要工作。

所以,如果您尝试做这样的事情,我建议您切入正题,跳过对 HTML/CSS 类型报告的挫败感,并使用 PDF。

【问题讨论】:

    标签: javascript html css printing


    【解决方案1】:

    您不能计算分页符,但可以计算分栏符,它们的行为非常相似。

    无论您在哪里使用分页符样式,都将它们与匹配的分栏符配对:

    -webkit-column-break-inside: avoid;
    -webkit-break-inside: avoid;
    

    然后将报告设置为使用与打印页面大小匹配的列:

    .page.precalc {
        width: 16800mm;
        height: 257mm;
        -webkit-column-width: 168mm;
        .content {
            width: 168mm;
        }
    }
    

    分栏符的工作方式与分页符非常相似,因此您可以简单地通过测量水平位置来确定元素的页码。

    var left = el.getBoundingClientRect().left;
    pageNumber = Math.round(left/635) + 1
    

    CSS 列的支持仍然有些参差不齐,因此可能无法正确打印。但是,您可以在完成布局计算后立即删除 .precalc 样式,以便视图返回到原始垂直布局。根据用例,屏幕/打印媒体查询也可以工作。

    以上内容适用于我使用 phantomjs 生成目录。让它在用户控制的任意浏览器中工作要复杂一些。

    【讨论】:

      【解决方案2】:

      下面的sn -p会产生;页面上每个 h2 之前的打印分页符。

      摘自here

      <style type="text/css">
        h2 {
          page-break-before: always;
        }
      </style>
      

      【讨论】:

        【解决方案3】:

        这将显示页码,但不显示总页数:

        footer {
            position:fixed;
            bottom:0;
            left:0;
        }
        
        body {
            counter-reset: page_number;
        }
        
        #page-number:after {
            counter-increment: page_number;
            content: "Page " counter(page_number);
        }
        

        有类似的东西

        <p id='page-number'></p>
        

        在页脚中。

        浏览器:Firefox 19.0.2

        【讨论】:

          【解决方案4】:

          我已经能够在使用 wkhtmltopdf 创建用于打印的 PDF 时实现分页符。 虽然我不确定我的解决方案是否与非 webkit 浏览器兼容,但我确信如果需要,您可以获得所有浏览器的供应商前缀。

          这就是我所做的,使用 page-break-inside: avoid;page-break-after: always;

          然后使用 jquery,我计算出我的部分的高度并计算(如果页面大小为 a4)发生了多少次中断,并使用 jquery 和 pdf 页脚动态编号页面(在创建 pdf 之前)所以当用户下载 pdf 时,它的编号是正确的。

          我建议设置页面(作为打印样式表),以便页码在页面的这些高度可见,也许使用绝对定位。

          但我认为这不是故障安全的。

          给他们一个 PDF 来打印,然后你有更多的控制,不必担心网络打印样式表,只要 PDF 下载链接显着显示。

          【讨论】:

          • 鉴于其他答案,我同意它不是故障安全的,但我建议为用户提供 pdf(您可以控制),然后您就不必担心他们如何打印您的页面。
          • 我确实检查了 wkhtmltopdf。由于与系统相关的其他一些原因,我试图避免使用 pdf,但如果共识说这是解决问题的唯一方法,我可以重新考虑。
          • 当我第一次发现需要时,我回避制作 PDF,认为这会花费太多精力,但我发现使用 wkhtmltopdf 很高兴,具有 webkit 的所有可靠性......它不是就像起初看起来一样艰难或令人沮丧。我强烈推荐它。
          • 我将不得不做更多关于 wkhtmltopdf 的谷歌搜索,看看是否能找到一些网站让我开始,这样我才能决定这对我来说是否是一个不错的选择。我试图避免计算所有页面大小,但这里的两个答案都让我这样做。
          • 使用 wkhtmltopdf,如果没有超出要显示的数字的任何计算(即不确定高度的诡计),页码可能不会很容易。如果您发布一个问题,询问如何通过一些漂亮的示例轻松设置它,(只需在此处评论它的链接)我会毫不犹豫地给出(据我所知)彻底的答案:)
          【解决方案5】:

          我假设您在每个报告的末尾放置一个 CSS 分页符,而不是在每个页面的末尾手动放置。因此,您的问题是知道何时会在长 HTML 文档中自然发生分页符。答案是——你不能。即使您知道一页可以容纳多少行表格(例如),您也只会知道给定的页面大小和打印设置。如果有人决定在 200% 的法律纸上打印您的报告,那么您的文档将永远不会知道这一点。在我看来,您的选择是 1)猜测或 2)不要担心。

          【讨论】:

          • 您对印刷变化的看法是正确的。我将 CSS 分页符放在每个报告的末尾。这是在 Intranet 上,因此尽管人们可以更改打印设置,但他们通常不会,如果他们这样做,我可以容忍在这些情况下解决方案“破坏”,因为我的回答可能是“不要那样做!” ;) 但我开始担心你可能是对的,这可能是不可能的......
          • 如果你们都使用相同的硬件和相同的设置,我只需将每个报告放在一个单独的 DIV 中,然后使用 theDiv.clientHeight 找出它的长度。如果您知道打印页面上适合的 DIV 尺寸,您应该知道有多少页。然后,您可以使用它所属的页码绝对定位 en 元素。这需要一些工作,但我认为它可以通过足够的试验和错误来工作。
          • 我将研究 clientHeight 选项。
          • 但是元素也会改变 div 的大小......这应该很有趣。
          • @ANeves 在绝对定位时不会。
          猜你喜欢
          • 2014-03-24
          • 2016-09-02
          • 2016-07-20
          • 1970-01-01
          • 1970-01-01
          • 2014-02-11
          • 2010-12-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多