如何更改每个页面的表头

时间:2013-12-18 12:06:27

标签: xml xslt xsl-fo

我被要求使用XSL-FO进行XSLT转换,以便从数据库创建可打印报告。到目前为止,所有这些都很好,但是报告中有一部分导致了一些麻烦。

fo:table-header对象中,我需要根据特定页面上显示的行来更改它。标题中有一个标题,需要反映当前显示的组的最新标题(只是数据库查询中有序文本字段的更改)。目前,只有两种类型的分组:传入消息和传出消息。

因此,假设传入组中有10条消息,传出组中有20条消息,而打印机只能在页面上容纳8条消息。

第一页将具有标题“传入消息”,然后是前8个消息。然后第二页将以标题“传入消息”开始,返回剩余的两个消息,然后(这一位我知道该怎么做),显示一个标题行,表明它现在已经转移到“传出消息”。同样,前6个消息将显示在该页面上,然后所有剩余页面将标题为“外发消息”。

我希望这描述了我想要实现的目标。我的想法目前是存储代码,以便在table-header内执行此操作,因为我找不到任何方法来检测table-body的foreach循环中的页面跳转。

如果有人有更好的想法,请加油,但如果使用这种方法有可行的解决方案,那就太棒了。

PS

如果有一个Wholey可分的消息数量与每页消息的数量相对应,那么下一页将不会引导前一个组,因为该组中不再有消息。

此外,虽然目前只有两个小组,但是已经讨论过将小组分成更多的小组,在这种情况下多达8个小组,但我相信他们将来会想要更多。< / p>

修改

我使用Apache FOP作为我的XSL-FO处理器,我输出为PDF。

查询产生的数据如下:

+----+-----+------+------+--------+--------+
| ID | DR  | SNDR | RCVR | DT     | MSGCHK |
+----+-----+------+------+--------+--------+
| 2  | IN  | 13   | 19   | 131201 | ...... |
+----+-----+------+------+--------+--------+
| 4  | IN  | 13   | 17   | 131205 | ...... |
+----+-----+------+------+--------+--------+
| 1  | OUT | 19   | 32   | 131119 | ...... |
+----+-----+------+------+--------+--------+
| 3  | OUT | 19   | 17   | 131203 | ...... |
+----+-----+------+------+--------+--------+
| 5  | OUT | 17   | 16   | 131204 | ...... |
+----+-----+------+------+--------+--------+

结果已由DIR ASC和DT DESC订购。因此,我的转换当前检查兄弟元素,如果它不同,它会输出一个带有colspan的行,该行包含一个带有新Direction的整行。例如:

+----------+--------+--------+------------------+
| Receiver | Sender | Date   | Message Checksum |
+----------+--------+--------+------------------+
| Incoming Messages:                            |
+----------+--------+--------+------------------+
| 13       | 19     | 131201 | ......           |
+----------+--------+--------+------------------+
| 13       | 17     | 131205 | ......           |
+----------+--------+--------+------------------+
| Outgoing Messages:                            |
+----------+--------+--------+------------------+
| 19       | 32     | 131119 | ......           |
+----------+--------+--------+------------------+
| 19       | 17     | 131203 | ......           |
+----------+--------+--------+------------------+
| 17       | 16     | 131204 | ......           |
+----------+--------+--------+------------------+

但我想要做的是,假设你每页只收到3封邮件,你会得到:

第1页:

+----------+--------+--------+------------------+
| Receiver | Sender | Date   | Message Checksum |
+----------+--------+--------+------------------+
| Incoming Messages:                            |
+----------+--------+--------+------------------+
| 13       | 19     | 131201 | ......           |
+----------+--------+--------+------------------+
| 13       | 17     | 131205 | ......           |
+----------+--------+--------+------------------+
| Outgoing Messages:                            |
+----------+--------+--------+------------------+
| 19       | 32     | 131119 | ......           |
+----------+--------+--------+------------------+

第2页:

+----------+--------+--------+------------------+
| Receiver | Sender | Date   | Message Checksum |
+----------+--------+--------+------------------+
| Outgoing Messages:                            |
+----------+--------+--------+------------------+
| 19       | 17     | 131203 | ......           |
+----------+--------+--------+------------------+
| 17       | 16     | 131204 | ......           |
+----------+--------+--------+------------------+

目前它的功能类似于此,但第2页的标题是Outgoing Messages不存在

1 个答案:

答案 0 :(得分:0)

我想为这种情况提供一个解决方案,可以忽略页面中的标题行数。当然,这有点难看,因为标题行也占用了空间,但它是第一种方法,并且计算文档中标题行数到特定行的特殊情况实际上很乏味(考虑到这种情况)哪一组具有与页面大小完全相同的大小!)。

需要做的是根据页面大小计算标题行检测新组。为了更清楚,XSLT为了清楚起见声明了局部变量。

假设我们有以下简化输入(你必须忍受我对XSL-FO的无知)

<?xml version="1.0" encoding="ISO-8859-1"?>
<rows>
  <row id="1" type="in"/>
  <row id="2" type="in"/>
  <row id="3" type="out"/>
  <row id="4" type="out"/>
  <row id="5" type="out"/>
  <row id="6" type="up"/>
  <row id="7" type="down"/>
  <row id="8" type="down"/>
</rows>

使用此XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

  <xsl:variable name="pagesize" select="3"/>

  <xsl:template match="rows">
    <table>
      <xsl:apply-templates/>
    </table>
  </xsl:template>

  <xsl:template match="row">
    <xsl:variable name="pagebreak" select="(count(preceding-sibling::row) mod $pagesize = 0) and count(preceding-sibling::row)>1"/>
    <xsl:variable name="new_group" select="(preceding-sibling::row)[last()]/@type != @type or count(preceding-sibling::row)=0"/>
    <xsl:if test="$pagebreak">
      <pagebreak/>
    </xsl:if>
    <xsl:if test="$pagebreak or $new_group">
      <header type="{@type}"/>
    </xsl:if>
    <tr id="{@id}" type="{@type}"/>
  </xsl:template>

</xsl:stylesheet>

您将获得以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<table>
  <header type="in"/>
  <tr id="1" type="in"/>
  <tr id="2" type="in"/>
  <header type="out"/>
  <tr id="3" type="out"/>
  <pagebreak/>
  <header type="out"/>
  <tr id="4" type="out"/>
  <tr id="5" type="out"/>
  <header type="up"/>
  <tr id="6" type="up"/>
  <pagebreak/>
  <header type="down"/>
  <tr id="7" type="down"/>
  <tr id="8" type="down"/>
</table>
相关问题