我被要求使用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
不存在
答案 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>