如何在使用 FOP 的 XSL-FO 中保留带有标题的表格但允许在表格主体内分页符

Posted

技术标签:

【中文标题】如何在使用 FOP 的 XSL-FO 中保留带有标题的表格但允许在表格主体内分页符【英文标题】:how to keep table with header but allow page breaks inside table body in XSL-FO using FOP 【发布时间】:2012-01-03 03:13:48 【问题描述】:

我正在使用 Apache FOP 和 XSL-FO 样式表生成 PDF。在 PDF 中,我输出属于表格的标题(html equiv h1),因此应始终保持在一起。但是,我的表格也可能包含太多数据,以至于它们不一定适合一页。

所需的结果是一个规则集,它允许标题与表格一起保留,并且尽可能将两者都放在一页上,但是如果表格数据太长以至于不能放在一页上,则分页符会插入到表格中,同时仍将标题元素与表格的开头保持在同一页面上。

我现在的解决方案确实将标题和表格保持在一起,但如果所有内容都无法放入一页,我会收到表格数据的内容溢出错误。我希望 page-break-inside: Avoid set on the table 元素会对此有所帮助,但显然不是......建议?

xsl 示例(为便于阅读而缩短):

<!-- add test table with header that should stay on same page -->
<fo:block font-size="20pt" font-weight="bold">Table header</fo:block>

<fo:table keep-with-previous.within-page="always"
      page-break-inside="avoid" 
      table-layout="fixed" border- border-style="solid">
  <fo:table-column column- />
  <fo:table-column column- />

  <fo:table-header text-align="center" background-color="silver">
    <fo:table-row>
      <fo:table-cell padding="1mm" border- border-style="solid">
    <fo:block>First name</fo:block>
      </fo:table-cell>
      <fo:table-cell padding="1mm" border- border-style="solid">
    <fo:block>Last name</fo:block>
      </fo:table-cell>
    </fo:table-row>
  </fo:table-header>
  <fo:table-body>
    <!-- the table-rows can be repeated N times, spanning several pages -->
    <fo:table-row >
      <fo:table-cell padding="1mm" border- border-style="solid">
    <fo:block>ab</fo:block>
      </fo:table-cell>
      <fo:table-cell padding="1mm" border- border-style="solid">
    <fo:block>cd</fo:block>
      </fo:table-cell>
    </fo:table-row>
    <!-- .... more table-row:s ---> 

更新所需的输出

为了更好地描述我正在寻找的结果:

结果文档包含文本段落、标题和表格。

    如果内容量使得表格在下一页上只有一或两行,则 xsl-fo 应将整个表格和标题移动到下一页,前提是它完全适合该页面. 另一方面,如果表格的行数太多以至于无论如何都无法放入一个全新的页面,则应立即在文档流中开始输出,同时仍允许将表格拆分为多个页面.

如果我删除 page-break-inside="avoid",那么我会得到一个很好地跨越多个页面的表格,但 #1 中描述的情况将不匹配。 IE。它不会移动表格,并且如果只有几行最终会移动到下一页,它会完全转到下一页。如果我离开 page-break-inside,那么我会遇到长表的内容溢出问题,因为不适合页面的行不会移动到下一页。

我想其中一个基本问题是我的输出表的长度非常动态,不幸的是我无法控制生成到表中的数据量。

【问题讨论】:

我可能在这里误解了一些东西,但是如果您删除page-break-inside: avoid,它不起作用是什么? @mzjn 看到我更新的问题,希望能稍微澄清一下这个问题? 【参考方案1】:

CSS 属性 page-break-inside="avoid" 映射到本机 FO 属性 keep-together="always"。这种映射是有问题的 IMO(但那是另一回事)。无论如何,我建议你使用原生 FO 属性keep-together.within-column="1" 而不是 page-break-inside。这允许 Apache FOP 在绝对必要时打破表内部。

【讨论】:

太棒了,正是我想要的。谢谢! @Jens Wegar:我很好奇,这对你真的有用吗(第 1 和第 2 种情况)?我曾尝试使用此解决方案,但对我而言,它只会解决案例#1。对于长表,FOP (1.0) 似乎试图将尽可能多的表保持在一起,并将表的开头推到下一页。 @mzjn:在我所做的测试中,解决方案达到了我的预期。但我对 XSL-FO 知之甚少,无法确定这是因为该解决方案有效,还是我的测试通过了巧合。然而,就目前而言,Jeremias 解决方案有效,因此我将其标记为已接受。

以上是关于如何在使用 FOP 的 XSL-FO 中保留带有标题的表格但允许在表格主体内分页符的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 xsl-fo 和 apache fop 0.95 显示固定的图像高度和宽度

使用fop在XSL-FO中设置字体

FOP XSL-FO 锚定在外部目的地

pdfbox / XSL + FOP 转换 PDF文档

pdfbox / XSL + FOP 转换 PDF文档

如何将带有嵌入图像的 XHTML+CSS 转换为 XSL-FO?