You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用XSLT实现XSL-FO固定位置表格分页(首页5行+续页提示)

固定位置表格的分页与提示实现方案

需求说明

需在**绝对定位的<fo:block-container>**中展示行数不固定的表格:

  • 首页仅显示表头+最多5行数据,若数据总行数超过5,在表格末尾添加「续见下页」提示
  • 剩余数据在新页面的对应位置生成完整表格(含表头+剩余数据行)
  • 最终用Apache FOP生成AFP/PDF文件

实现思路

由于绝对定位容器无法依赖FOP自动分页机制,需通过XSLT手动拆分数据:

  1. 统计InstallmentPlan节点总数,判断是否需要分页
  2. 首页表格仅渲染前5条数据,根据总数判断是否添加提示行
  3. 若存在剩余数据,生成新页面并渲染表头+剩余数据行

完整代码示例

首页固定位置表格

<fo:block-container border="solid 1px" absolute-position="absolute" left="3.09in" top="2.95in" width="4.765in" height="1.1in" overflow="hidden">
    <fo:table table-layout="fixed" width="100%">
        <fo:table-body>
            <!-- 表头行 -->
            <fo:table-row>
                <fo:table-cell>
                    <fo:block padding-left="2.0mm" padding="2pt" font-family="TelenorTFBold" font-size="11pt" font-weight="normal" fox:border-before-start-radius="5pt" fox:border-before-end-radius="5pt" fox:border-after-start-radius="5pt" fox:border-after-end-radius="5pt" background-color="#f8f8f8">
                        <xsl:call-template name="LabelText">
                            <xsl:with-param name="Code" select="concat($language, 'Number')"/>
                        </xsl:call-template>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block padding-left="2.0mm" padding="2pt" font-family="TelenorTFBold" font-size="11pt" font-weight="normal" fox:border-before-start-radius="5pt" fox:border-before-end-radius="5pt" fox:border-after-start-radius="5pt" fox:border-after-end-radius="5pt" background-color="#f8f8f8">
                        <xsl:call-template name="LabelText">
                            <xsl:with-param name="Code" select="concat($language, 'duedate')"/>
                        </xsl:call-template>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block text-align="right" padding-left="2.0mm" padding="2pt" font-family="TelenorTFBold" font-size="11pt" font-weight="normal" fox:border-before-start-radius="5pt" fox:border-before-end-radius="5pt" fox:border-after-start-radius="5pt" fox:border-after-end-radius="5pt" background-color="#f8f8f8">
                        <xsl:call-template name="LabelText">
                            <xsl:with-param name="Code" select="concat($language, 'Total')"/>
                        </xsl:call-template>
                    </fo:block>
                </fo:table-cell>
            </fo:table-row>

            <!-- 渲染前5条数据行 -->
            <xsl:for-each select="InstallmentPlan[position() &lt;= 5]">
                <fo:table-row>
                    <fo:table-cell font-family="TelenorTF" font-size="7pt" font-weight="normal">
                        <fo:block padding-after="0.15cm" white-space-collapse="false">
                            <xsl:value-of select="InstallmentNumber"/>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell font-family="TelenorTF" font-size="7pt" font-weight="normal">
                        <fo:block padding-after="0.15cm" white-space-collapse="false">
                            <xsl:value-of select="DueDate"/>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell font-family="TelenorTF" font-size="7pt" font-weight="normal">
                        <fo:block text-align="right" padding-after="0.15cm" white-space-collapse="false">
                            <xsl:call-template name="format_amount">
                                <xsl:with-param name="amount" select="Amount"/>
                            </xsl:call-template>
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </xsl:for-each>

            <!-- 数据总数超过5时添加提示行 -->
            <xsl:if test="count(InstallmentPlan) > 5">
                <fo:table-row>
                    <fo:table-cell number-columns-spanned="3">
                        <fo:block text-align="right" padding-right="2.0mm" padding-top="2pt" font-family="TelenorTF" font-size="7pt">
                            续见下页
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </xsl:if>
        </fo:table-body>
    </fo:table>
</fo:block-container>

剩余数据的新页面渲染

在首页内容后添加以下代码处理剩余数据:

<!-- 存在剩余数据时生成新页面 -->
<xsl:if test="count(InstallmentPlan) > 5">
    <fo:page-sequence master-reference="你的页面模板名称">
        <fo:flow flow-name="xsl-region-body">
            <!-- 新页面表格容器,位置与首页保持一致 -->
            <fo:block-container border="solid 1px" absolute-position="absolute" left="3.09in" top="2.95in" width="4.765in">
                <fo:table table-layout="fixed" width="100%">
                    <fo:table-body>
                        <!-- 重复表头行 -->
                        <fo:table-row>
                            <fo:table-cell>
                                <fo:block padding-left="2.0mm" padding="2pt" font-family="TelenorTFBold" font-size="11pt" font-weight="normal" fox:border-before-start-radius="5pt" fox:border-before-end-radius="5pt" fox:border-after-start-radius="5pt" fox:border-after-end-radius="5pt" background-color="#f8f8f8">
                                    <xsl:call-template name="LabelText">
                                        <xsl:with-param name="Code" select="concat($language, 'Number')"/>
                                    </xsl:call-template>
                                </fo:block>
                            </fo:table-cell>
                            <fo:table-cell>
                                <fo:block padding-left="2.0mm" padding="2pt" font-family="TelenorTFBold" font-size="11pt" font-weight="normal" fox:border-before-start-radius="5pt" fox:border-before-end-radius="5pt" fox:border-after-start-radius="5pt" fox:border-after-end-radius="5pt" background-color="#f8f8f8">
                                    <xsl:call-template name="LabelText">
                                        <xsl:with-param name="Code" select="concat($language, 'duedate')"/>
                                    </xsl:call-template>
                                </fo:block>
                            </fo:table-cell>
                            <fo:table-cell>
                                <fo:block text-align="right" padding-left="2.0mm" padding="2pt" font-family="TelenorTFBold" font-size="11pt" font-weight="normal" fox:border-before-start-radius="5pt" fox:border-before-end-radius="5pt" fox:border-after-start-radius="5pt" fox:border-after-end-radius="5pt" background-color="#f8f8f8">
                                    <xsl:call-template name="LabelText">
                                        <xsl:with-param name="Code" select="concat($language, 'Total')"/>
                                    </xsl:call-template>
                                </fo:block>
                            </fo:table-cell>
                        </fo:table-row>

                        <!-- 渲染剩余数据行 -->
                        <xsl:for-each select="InstallmentPlan[position() > 5]">
                            <fo:table-row>
                                <fo:table-cell font-family="TelenorTF" font-size="7pt" font-weight="normal">
                                    <fo:block padding-after="0.15cm" white-space-collapse="false">
                                        <xsl:value-of select="InstallmentNumber"/>
                                    </fo:block>
                                </fo:table-cell>
                                <fo:table-cell font-family="TelenorTF" font-size="7pt" font-weight="normal">
                                    <fo:block padding-after="0.15cm" white-space-collapse="false">
                                        <xsl:value-of select="DueDate"/>
                                    </fo:block>
                                </fo:table-cell>
                                <fo:table-cell font-family="TelenorTF" font-size="7pt" font-weight="normal">
                                    <fo:block text-align="right" padding-after="0.15cm" white-space-collapse="false">
                                        <xsl:call-template name="format_amount">
                                            <xsl:with-param name="amount" select="Amount"/>
                                        </xsl:call-template>
                                    </fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                        </xsl:for-each>
                    </fo:table-body>
                </fo:table>
            </fo:block-container>

            <!-- 新页面其他内容 -->
            <fo:block>信息区域</fo:block>
        </fo:flow>
    </fo:page-sequence>
</xsl:if>

关键说明

  • 通过count(InstallmentPlan)判断数据总数,控制提示和新页面的生成
  • 用position()筛选数据行,实现精准拆分
  • 新页面的表格容器位置需与首页保持一致,确保视觉统一
  • 若剩余数据仍需多分页,可重复上述逻辑(如每5行一页)

内容的提问来源于stack exchange,提问作者Pooja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:44:50