HTML中可预测且一致的跨浏览器打印

时间:2014-09-10 19:06:24

标签: css html5 svg printing printing-web-page

我试图弄清楚是否有办法直接从HTML实现理智打印。我们的用户通常希望打印几页以用于他们自己的记录。打印输出包含Google Charts,网格由bootstrap处理。我们经常需要每页一组内容,因此非常需要分页。

传统上我们已经使用过印刷媒体查询,但是几乎不可能在浏览器中实现一致的结果,比如Firefox,Chrome和Mobile Safari等。片断会溢出,分页会被忽略等等

亚马逊和Newegg等公司为客户提供打印发票和其他页面的能力。似乎通常涉及单独的仅打印版本的内容,或者是所有表格或非常简化的标记,在打印时看起来非常基本。一般来说,几乎没有造型,很少有图像,绝对没有,也没有任何分页。据我所知。

另一种选择是将所有内容转换为PDF,但这有其自身的缺陷和费用。现在,您必须为每个需要打印的页面以第二种格式重新生成相同的内容,并且完美样式化PDF也是非常重要的。

有什么可以帮助解决这个问题吗?任何普遍接受的解决方案?

2 个答案:

答案 0 :(得分:2)

我们使用wkhtmltopdf和PrinceXML来获得一致的样式。两者都是命令行工具,可以采用URL加上自定义CSS文件。它们生成一致的输出,并且与浏览器无关,因为它们是渲染引擎。

我们曾经使用wkhtmltopdf,但我们开始转向PrinceXML,因为它支持边距框和两列布局。 (PrinceXML的主要警告是价格。)

完美造型PDF并不比网页显示的样式更糟或更难。我的经验是,需要一两个小时才能正确设置打印页面的样式。我从未尝试过处理Google Charts。

答案 1 :(得分:1)

现在,所有流行的桌面浏览器都支持用于设置页边距的CSS @page rule,以及用于处理分页符的CSS属性page-break-insidepage-break-beforepage-break-after。这些通常会提供足够的控制来实现一致的跨平台打印,但有一些东西只有一个或两个浏览器可以做。一些例子是:

  • 页码编号
  • 运行页眉和页脚
  • 孤儿/寡妇控制
  • 控制背景颜色

如果您需要这些东西,PDF可能是您的最佳选择;否则,它可能是矫枉过正的。 PDF转换器不会自动确定对您投入的任何内容进行分页的理想方式;仍然需要人类判断。

但这并不意味着您需要明确声明每个分页符的位置。防止不良分页通常比强制分页更容易。换句话说,不要告诉浏览器想要分页的地方,而是告诉它想要它们。

您可能希望阻止分页符的地方示例:

  • 在节标题和节文本的第一行之间
  • 表格的列标题和第一行数据*
  • 之间
  • 在密切相关的表格字段之间。

这些情况下的首选CSS声明是page-break-inside: avoid; **。在前两个示例中使用page-break-after: avoid;会更容易,但Firefox仅支持该属性的alwaysauto值。因此,您必须创建一个不可破坏的div,它包含或重叠您想要保持在一起的内容。这是一种方法:

<style>
  .section {
    line-height: 1.25em;
  }
  .title {
    page-break-inside: avoid;
    padding-bottom: 1.25em;
    font-weight: bold;
  }
  .overlap {
    margin-bottom: -1.25em;
  }
</style>

<div class="section">
  <div class="title">
    Title of This Section
  </div>
  <div class="overlap">
  </div>
  This is the section text. It could be any length, so we have to
  allow page breaks in it. However, we don't want the first line to
  be separated from the section title. The title is unbreakable, so
  we just need to add some bottom padding to it and make it overlap
  the first line of text.
</div>  

*表格可能是跨浏览器一致打印的最具挑战性的事情,但it is possible

**旧版本的Firefox,Chrome和Safari不支持CSS声明page-break-inside: avoid;,但如果需要,您可以使用display: inline-block;获得相同的效果。

相关问题