3
votes

I'm generating some PDF documents with XSL-FO and have some tables that can span over multiple pages. In those cases, what I want to do is to repeat the table's header at the beginning of every new page, with a "(continued)" label on all pages except the first one.

My XSL code :

<xsl:template name="Tooling">
    <fo:table xsl:use-attribute-sets="tableDefaultLayout">
        <fo:table-column column-width="37mm" />
        <fo:table-column column-width="37mm" />
        <fo:table-column column-width="74mm" />
        <fo:table-column column-width="37mm" />
        <fo:table-header xsl:use-attribute-sets="categoryDefaultFont">
            <fo:table-row height="7.7mm" border="0pt solid black" display-align="before" text-align="start">
                <fo:table-cell number-columns-spanned="4" font-size="12pt">
                    <fo:block margin-top="3mm">
                        <fo:retrieve-table-marker retrieve-class-name="continued" 
            retrieve-position-within-table="first-starting" 
            retrieve-boundary-within-table="table-fragment"/>
            &#x00A0;
                    </fo:block>
                </fo:table-cell>
            </fo:table-row>
            <fo:table-row xsl:use-attribute-sets="defaultBodyRow" height="4.7mm" border="0pt solid black">
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Item No.</xsl:text>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Part No.</xsl:text>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Description</xsl:text>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Qty Reqd</xsl:text>
                    </fo:block>
                </fo:table-cell>
            </fo:table-row>
        </fo:table-header>
        <fo:table-body xsl:use-attribute-sets="valueDefaultFont" font-size="8pt">
            <xsl:for-each select="1 to 50">
                <fo:table-row xsl:use-attribute-sets="defaultBodyRow" border="0pt solid black">
                    <fo:table-cell>
                        <fo:block>
                            <xsl:choose>
                                <xsl:when test="position()=1">
                                    <fo:marker marker-class-name="continued">
                                        <xsl:text>TOOLING:-</xsl:text>
                                    </fo:marker>
                                </xsl:when>
                                <xsl:otherwise>
                                    <fo:marker marker-class-name="continued">
                                        <xsl:text>TOOLING: (continued)</xsl:text>
                                    </fo:marker>
                                </xsl:otherwise>
                            </xsl:choose>
                            <xsl:text>G3@ITEMSEQ</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:text>G3@PARTNO</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:text>G3@PARTDESC</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:text>G3@PARTQTY</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </xsl:for-each>
        </fo:table-body>
    </fo:table>
</xsl:template>

And the FO generated :

<fo:table border-bottom="0.5pt solid black" border-collapse="collapse" border-left="1pt solid black" border-right="1pt solid black" border-top="0.5pt solid black" margin="0mm" padding="0mm" table-layout="fixed" width="100%">
                <fo:table-column column-width="37mm"/>
                <fo:table-column column-width="37mm"/>
                <fo:table-column column-width="74mm"/>
                <fo:table-column column-width="37mm"/>
                <fo:table-header font-family="sans-serif" font-size="10pt" font-weight="bold">
                    <fo:table-row border="0pt solid black" display-align="before" height="7.7mm" text-align="start">
                        <fo:table-cell font-size="12pt" number-columns-spanned="4">
                            <fo:block margin-top="3mm">
                                <fo:retrieve-table-marker retrieve-boundary-within-table="table-fragment" retrieve-class-name="continued" retrieve-position-within-table="first-starting"/>
             
                            </fo:block>
                        </fo:table-cell>
                    </fo:table-row>
                    <fo:table-row border="0pt solid black" display-align="center" height="4.7mm" keep-together.within-page="always" text-align="center">
                        <fo:table-cell>
                            <fo:block>Item No.</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>Part No.</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>Description</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>Qty Reqd</fo:block>
                        </fo:table-cell>
                    </fo:table-row>
                </fo:table-header>
                <fo:table-body font-family="monospace" font-size="8pt" font-weight="normal">
                    <fo:table-row border="0pt solid black" display-align="center" height="7.74mm" keep-together.within-page="always" text-align="center">
                        <fo:table-cell>
                            <fo:block>
                                <fo:marker marker-class-name="continued">TOOLING:-</fo:marker>G3@ITEMSEQ</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>G3@PARTNO</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>G3@PARTDESC</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>G3@PARTQTY</fo:block>
                        </fo:table-cell>
                    </fo:table-row>
                    <fo:table-row border="0pt solid black" display-align="center" height="7.74mm" keep-together.within-page="always" text-align="center">
                        <fo:table-cell>
                            <fo:block>
                                <fo:marker marker-class-name="continued">TOOLING: (continued)</fo:marker>G3@ITEMSEQ</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>G3@PARTNO</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>G3@PARTDESC</fo:block>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block>G3@PARTQTY</fo:block>
                        </fo:table-cell>
                    </fo:table-row>

Then continues for 50 rows : as you can see the first one has a marker "TOOLING:-" and all the others have a marker "TOOLING: (continued)", which is what I want.

My problem is that I can't seem to make the fo:retrieve-table-marker object to work properly : I have tried multiple combinations with the "retrieve-position" and "retrieve-boundary" attributes but each time the first line of my header is always blank, on the first or on the other pages.

If someone could explain to me what I'm doing wrong with these "fo:retrieve-table-marker" and "fo:marker" object, that would be a real help, I've been struggling with this issue for a few days now.

2
I had a similar problem a while ago (trying to retrieve a marker before the first fo:marker occurrence), and worked around it by placing an extra instance of fo:marker before my first retrieve-marker. Not the way it should work, though.Hobbes
You have set table-omit-header-at-break="true". Since markers can only be used in table header, if you don't ask to display the table header, the Continued won't appear. Otherwise the rest of your code is correct.potame
Sorry, the "table-omit-header-at-break" is a copy/paste error, I tried to add this attribute to see what it did but it actually has no relation with my problem. @Hobbes thanks for the tip, I'm going to try thiseipiplusun

2 Answers

0
votes

You have set table-omit-header-at-break="true". Since markers can only be used in table header, if you don't ask to display the table header, the Continued won't appear. Otherwise the rest of your code is correct.

Thus I would correct your XSLT code as follows:

First, remove the <xsl:attribute name="table-omit-header-at-break">true</xsl:attribute> that may be found elsewhere in the stylesheet, within the <xsl:attribute-set name="tableDefaultLayout"> definition.

Then modify your template like so:

<xsl:template name="Tooling">
    <fo:table xsl:use-attribute-sets="tableDefaultLayout">
        <fo:table-column column-width="37mm" />
        <fo:table-column column-width="37mm" />
        <fo:table-column column-width="74mm" />
        <fo:table-column column-width="37mm" />
        <fo:table-header xsl:use-attribute-sets="categoryDefaultFont">
            <fo:table-row height="7.7mm" border="0pt solid black" display-align="before" text-align="start">
                <fo:table-cell number-columns-spanned="4" font-size="12pt">
                    <fo:block margin-top="3mm">
                        <fo:retrieve-table-marker retrieve-class-name="continued" 
            retrieve-position-within-table="first-starting" 
            retrieve-boundary-within-table="table-fragment"/>
            &#x00A0;
                    </fo:block>
                </fo:table-cell>
            </fo:table-row>
        </fo:table-header>
        <fo:table-body xsl:use-attribute-sets="valueDefaultFont" font-size="8pt">
            <fo:table-row xsl:use-attribute-sets="defaultBodyRow" height="4.7mm" border="0pt solid black">
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Item No.</xsl:text>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Part No.</xsl:text>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Description</xsl:text>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>
                        <xsl:text>Qty Reqd</xsl:text>
                    </fo:block>
                </fo:table-cell>
            </fo:table-row>
            <xsl:for-each select="1 to 50">
                <fo:table-row xsl:use-attribute-sets="defaultBodyRow" border="0pt solid black">
                    <fo:table-cell>
                        <fo:block>
                            <xsl:choose>
                                <xsl:when test="position()=1">
                                    <fo:marker marker-class-name="continued">
                                        <xsl:text>TOOLING:-</xsl:text>
                                    </fo:marker>
                                </xsl:when>
                                <xsl:otherwise>
                                    <fo:marker marker-class-name="continued">
                                        <xsl:text>TOOLING: (continued)</xsl:text>
                                    </fo:marker>
                                </xsl:otherwise>
                            </xsl:choose>
                            <xsl:text>G3@ITEMSEQ</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:text>G3@PARTNO</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:text>G3@PARTDESC</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:text>G3@PARTQTY</xsl:text>
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </xsl:for-each>
        </fo:table-body>
    </fo:table>
</xsl:template>
0
votes

As an alternative to generating the fo:marker in every row:

<fo:table-header xsl:use-attribute-sets="categoryDefaultFont">
    <fo:table-row height="7.7mm" border="0pt solid black"
                  display-align="before" text-align="start">
        <fo:table-cell number-columns-spanned="4" font-size="12pt">
            <fo:block margin-top="3mm">TOOLING:-<fo:retrieve-table-marker
                    retrieve-class-name="continued" 
                    retrieve-position-within-table="last-starting"/>
            </fo:block>
        </fo:table-cell>
    </fo:table-row>
    ...
</fo:table-header>
<fo:table-body xsl:use-attribute-sets="valueDefaultFont" font-size="8pt">
    <fo:marker marker-class-name="continued" />
    <fo:marker marker-class-name="continued"> (continued)</fo:marker>
    <xsl:for-each select="1 to 50">
        <fo:table-row xsl:use-attribute-sets="defaultBodyRow"
                      border="0pt solid black">
  ...