Search code examples
xsltxslt-2.0xsl-foapache-fop

How to avoid splitting of table at page end in Apache fop


I am trying to create a PDF using Apache FOP. I have a section of input which repeats as many number of times. With each section i have a table created in the page. After about 3 tables, there is a page break and the table is split into the current and the next page. I would want to avoid this and have the entire table in the next page. Could you please guide as i am very new to Apache FOP.

XML section that contributes for table :

<SummaryDetails> 
<SummaryDetail>
<MediaType>P</MediaType>
<T1>
<T1ID>I</T1ID>
<T2>
<T2ID>T2</T2ID>
 <T3>
 <T3ID>T3</T3ID>
 </T3>
 </T2>
 /T1>
 </SummaryDetail>
 </SummaryDetails>

Code snippet:

The table consists of nested loop for T1, T2 and T3 sections in the xml. The table appears ok until it encounters a page break.

<fo:page-sequence master-reference="A4-first" force-page-count="no-force" id="end">

<!--Header of table which appears in all pages-->
<fo:static-content flow-name="xsl-region-before">
<fo:table >
<fo:table-column column-width="5.8cm"/>
<fo:table-column column-width="8.1cm"/>
<fo:table-column column-width="4.8cm"/>
<fo:table-body>
<fo:table-row height="3.1cm">
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:static-content>

<!--Body of table-->
<fo:flow flow-name="body">
<!--This table appears only when the number of SummaryDetails section is greater than 1 and 
appears just once-->
<xsl:choose>
<xsl:when test="count(./SummaryDetails) &gt; 1">
<fo:table margin-left="0.2cm"  >
<fo:table-body>
<fo:table-row>
</fo:table-row>
</fo:table-body>
</fo:table>
</xsl:when>
</xsl:choose>

<!--This is the table which is having the issue-->
<fo:table>
<fo:table-body>
<xsl:for-each select="SummaryDetails">
<fo:table-row >
</fo:table-row>

<xsl:for-each select="SummaryDetail/T1">
<fo:table-row >
</fo:table-row>
<xsl:for-each select="T2">
<fo:table-row >
</fo:table-row>
<xsl:for-each select="T3">       
<fo:table-row >
</fo:table-row>
</xsl:for-each>
<fo:table-row >
</fo:table-row>
</xsl:for-each>
<fo:table-row>
</fo:table-row>
</xsl:for-each>
<fo:table-row>
</fo:table-row>
<fo:table-row>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>

The input xml is also explained here : How to insert a new page when a table inside a for each block overflows from the current page sequence in Apache fop


Solution

  • I tried using keep-with-next.within-page="always" in every row of the table and keep-with-next.within-page="always" on the 1st table cell and it worked out wonders. :)

    <!--This is the table which is having the issue-->
    <fo:table>
    <fo:table-body>
    <xsl:for-each select="SummaryDetails">
    <fo:table-row keep-with-next.within-page="always">
    <fo:table-cell keep-with-next.within-page="always"></fo:table-cell>
    </fo:table-row>
    
    <xsl:for-each select="SummaryDetail/T1">
    <fo:table-row keep-with-next.within-page="always">
    <fo:table-cell keep-with-next.within-page="always"></fo:table-cell>
    </fo:table-row>
    <xsl:for-each select="T2">
    <fo:table-row keep-with-next.within-page="always">
    </fo:table-row>
    <xsl:for-each select="T3">       
    <fo:table-row keep-with-next.within-page="always">
    </fo:table-row>
    </xsl:for-each>
    <fo:table-row keep-with-next.within-page="always">
    </fo:table-row>
    </xsl:for-each>
    <fo:table-row keep-with-next.within-page="always">
    </fo:table-row>
    </xsl:for-each>
    <fo:table-row keep-with-next.within-page="always">
    </fo:table-row>
    <fo:table-row keep-with-next.within-page="always">
    </fo:table-row >
    </xsl:for-each>
    </fo:table-body>
    </fo:table>