XSL FO Customized Table requirement - xslt

I have below requirement.
I have below table in xml.
------------------------------------------------------------
|NAME |NUMBER|<<Empty>>|NAME |NUMBER|<<Empty>>|NAME |NUMBER|
------------------------------------------------------------
|A001 | 1 | |A005 | 5 | |A009 | 9 |
-------------- -------------- --------------
|A002 | 2 | |A006 | 6 | |A010 | 10 |
-------------- -------------- --------------
|A003 | 3 | |A007 | 7 | |A011 | 11 |
-------------- -------------- --------------
|A004 | 4 | |A008 | 8 | |A011 | 12 |
------------------------------------------------------------
Using XSL FO and Rendrex the above XML has been shown as below:
Case 1: If the above table appeared in single page it should appear as below:
|NAME |NUMBER|<<Empty>>|NAME |NUMBER|<<Empty>>|NAME |NUMBER|
------------------------------------------------------------
|A001 | 1 | |A005 | 5 | |A009 | 9 |
-------------- -------------- --------------
|A002 | 2 | |A006 | 6 | |A010 | 10 |
-------------- -------------- --------------
|A003 | 3 | |A007 | 7 | |A011 | 11 |
-------------- -------------- --------------
|A004 | 4 | |A008 | 8 | |A011 | 12 |
------------------------------------------------------------
Case 2: If the table appeared in two page it should appear as below:
-------------------------------------------------
|NAME |NUMBER| |NAME |NUMBER| |NAME |NUMBER|
-------------------------------------------------
|A001 | 1 | |A003 | 3 | |A005 | 5 | ---> Page 1
|A002 | 2 | |A004 | 4 | |A006 | 6 |
-------------------------------------------------
-------------------------------------------------
|NAME |NUMBER| |NAME |NUMBER| |NAME |NUMBER|
-------------------------------------------------
|A007 | 7 | |A009 | 9 | |A011 | 11 | ---> Page 2
|A008 | 8 | |A010 | 10 | |A012 | 12 |
-------------------------------------------------
I am able to achieve the Case 1 but case 2 i am getting like below:
-------------------------------------------------
|NAME |NUMBER| |NAME |NUMBER| |NAME |NUMBER|
-------------------------------------------------
|A001 | 1 | |A005 | 5 | |A009 | 9 | --> Page 1
|A002 | 2 | |A006 | 6 | |A010 | 10 |
-------------------------------------------------
-------------------------------------------------
|NAME |NUMBER| |NAME |NUMBER| |NAME |NUMBER|
-------------------------------------------------
|A003 | 3 | |A007 | 7 | |A011 | 11 | --> Page 2
|A004 | 4 | |A008 | 8 | |A011 | 12 |
-------------------------------------------------
Used XSL:
<fo:table-and-caption id="Table2" caption-side="before" >
<fo:table hyphenate="true" >
<fo:table-header> <!--- Header start -->
<fo:table-row keep-together.within-page="always">
<fo:table-cell >
<fo:block><xsl:value-of select="$headerValues[1]/para"/></fo:block> <!-- NAME-->
</fo:table-cell>
<fo:table-cell >
<fo:block><xsl:value-of select="$headerValues[2]/para"/></fo:block> <!--NUMBER -->
</fo:table-cell>
<fo:table-cell > <!--- Blank Cells in header-->
<fo:block> </fo:block>
</fo:table-cell>
<fo:table-cell >
<fo:block><xsl:value-of select="$headerValues[1]/para"/></fo:block> <!--NAME -->
</fo:table-cell>
<fo:table-cell >
<fo:block><xsl:value-of select="$headerValues[2]/para"/></fo:block> <!--NUMBER -->
</fo:table-cell>
<fo:table-cell > <!--- Blank Cells in header-->
<fo:block> </fo:block>
</fo:table-cell>
<fo:table-cell >
<fo:block><xsl:value-of select="$headerValues[1]/para"/></fo:block> <!--NAME -->
</fo:table-cell>
<fo:table-cell >
<fo:block><xsl:value-of select="$headerValues[2]/para"/></fo:block> <!--NUMBER -->
</fo:table-cell>
</fo:table-row>
</fo:table-header> <!--- Header End -->
<fo:table-body>
<xsl:for-each select="1 to $row-size">
<xsl:variable name="iterationValue" select="."/>
<fo:table-row keep-together.within-page="always">
<fo:table-cell align="left" > <!-- First Cell -->
<fo:block><xsl:value-of select="$nodeValues[$iterationValue]/entry[1]/para"/> </fo:block>
</fo:table-cell>
<fo:table-cell > <!--Second Cell -->
<fo:block><xsl:value-of select="$nodeValues[$iterationValue]/entry[2]/para"/></fo:block>
</fo:table-cell>
<xsl:choose>
<xsl:when test="$iterationValue = $row-size">
<fo:table-cell border-top = "0pt"> </fo:table-cell> <!--Third blank cell -->
</xsl:when>
<xsl:otherwise>
<fo:table-cell ></fo:table-cell>
</xsl:otherwise>
</xsl:choose>
<!-- For 2nd column in table -->
<xsl:choose>
<xsl:when test ="$iterationValue + $row-size > $rowCount">
<fo:table-cell >
<fo:block>-</fo:block> <!-- To Fill - in case of blank -->
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell >
<fo:block><xsl:value-of select="$nodeValues[$iterationValue + $row-size]/entry[1]/para"/> </fo:block>
</fo:table-cell>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test ="$iterationValue + $row-size > $rowCount">
<fo:table-cell >
<fo:block>-</fo:block> <!-- To Fill - in case of blank -->
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell >
<fo:block><xsl:value-of select="$nodeValues[$iterationValue + $row-size]/entry[2]/para"/></fo:block> </fo:table-cell>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="$iterationValue = $row-size">
<fo:table-cell border-top = "0pt"> </fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell ></fo:table-cell> <!-- Blank cell -->
</xsl:otherwise>
</xsl:choose>
<!-- For Third column in table -->
<xsl:choose>
<xsl:when test ="$iterationValue + (2*$row-size) > $rowCount">
<fo:table-cell >
<fo:block>-</fo:block>
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell >
<fo:block><xsl:value-of select="$nodeValues[$iterationValue + (2*$row-size)]/entry[1]/para"/> </fo:block>
</fo:table-cell>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test ="$iterationValue + (2*$row-size) > $rowCount">
<fo:table-cell >
<fo:block>-</fo:block>
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell >
<fo:block><xsl:value-of select="$nodeValues[$iterationValue + (2*$row-size)]/entry[2]/para"/></fo:block>
</fo:table-cell>
</xsl:otherwise>
</xsl:choose>
</fo:table-row>
</xsl:for-each >
</fo:table-body>
</fo:table>
</fo:table-and-caption>
Can someone please help me to find out the solution.
Expected Output:

Because you are using RenderX, you can use rx:flow-section for the table to make a three-column area within the flow. Remember to add the rx: extension namespace to your XSL and you can completely forgo the complicated numbering.
If you examine the below XSL FO it achieves your desire. Note that I have set the column-gap to "0pt" so that it looks like a continuous table. This will work if all your row-heights are the same.
XSL FO:
<rx:flow-section column-count="3" column-gap="0pt">
<fo:table width="100%">
<fo:table-body>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>1</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>2</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>3</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>4</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>5</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>6</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>7</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>8</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>9</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>10</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>11</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>12</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>13</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>14</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>15</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>16</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>17</fo:block></fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black"><fo:block>Name</fo:block></fo:table-cell>
<fo:table-cell border="1pt solid black"><fo:block>18</fo:block></fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</rx:flow-section>
The output when crossing a page boundary:

You can achieve an output that is almost what you requested using a much simpler table and a slightly more complicated page-master:
the table: just two columns (one for NAME and one for NUMBER), the fo:table-header and the fo:table-body with rows in the "natural" order (1, 2, 3, ..., 12)
the page master: add columns to the fo:region-body definition, using column-count="3" and column-gap="1cm" (or something appropriate)
The result is a table whose rows flow in the three region columns, eventually creating other pages if needed.
You may use an empty <fo:block span="all"/> after the table, so that the columns will be balanced (so that, for example, you will have 2 rows in each column instead of having 4 in the first column, 2 in the second one and 0 in the third one).
The only requirement that this solution cannot satisfy is the continuous border from margin to margin.

Related

How to wirte a part of <fo:table> in a function

I have to create many <fo:table-row> in a <fo:table-body>. I think it's not nice if I write almost 5 lines of code several times (Maybe 50 times) to create the rows.
Like this:
<fo:table-body>
<fo:table-row>
<fo:table-cell padding-bottom="6pt">
<fo:value-of select="row1"/>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell padding-bottom="6pt">
<fo:value-of select="row2"/>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell padding-bottom="6pt">
<fo:value-of select="row3"/>
</fo:table-cell>
</fo:table-row>
....
</fo:table-body>
I tried to write a function that writes the <fo:table-row> for me. And I have to call the function every time and pass a parameter.
<xsl:function name="fn:createRow">
<xsl:param name="string1"/>
<fo:table-row>
<fo:table-cell padding-bottom="6pt">
<fo:value-of select="$string1"/>
</fo:table-cell>
</fo:table-row>
</xsl:function>
And now my XSLT look like this.
<fo:table-body>
<fo:block>
<fo:value-of select="fn:createRow('row1')"/>
<fo:value-of select="fn:createRow('row2')"/>
</fo:block>
</fo:table-body>
But I get the error:
"fo:block" is not a valid child of "fo:table-body"!
But when I work without <fo:block> I get nothing in the PDF:
<fo:table-body>
<fo:value-of select="fn:createRow('row1')"/>
<fo:value-of select="fn:createRow('row2')"/>
</fo:table-body>
Is there any opportunity to do it?
Thanks!
fo:table-cell can contain one or more block-level FOs, including fo:block. (See https://www.w3.org/TR/xsl11/#fo_table-cell)
You don't show your XML, but if all of the row* elements are contained by one element, then in the template for that element, you could do something like:
<fo:table>
<fo:table-body>
<xsl:for-each select="*">
<fo:table-row>
<fo:table-cell padding-bottom="6pt">
<fo:block>
<!-- The row* element is the current element here. -->
<xsl:apply-templates />
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:for-each>
</fo:table-body>
</fo:table>
Alternatively, you could make a template for all of the row* elements:
<xsl:template match="*[starts-with(local-name(), 'row')]">
<fo:table-row>
...
(From this distance, it's not clear why the row elements need separate element names.)
When you know the names of the elements that you want to format, you can do:
<xsl:apply-templates select="row1, row2, row3" />
and:
<xsl:template match="row1 | row2 | row3">
<fo:table-row>
...
I think instead of <fo:value-of select="$string1"/> you want <xsl:value-of select="$string1"/>. I would also check whether a fo:table-cell allows inline content, it might be necessary to put a fo:block container in the cell which has the xsl:value-of element as a child.
Also, for the function calls, don't use <fo:value-of select="fn:createRow('row1')"/>, instead, use <xsl:sequence select="fn:createRow('row1')"/>.
Also, fn is a reserved prefix, for your own functions declare and use your own namespace (e.g. xmlns:mf="http://example.com/mf" and <xsl:function name="mf:createRow" ...>...</xsl:function>, then use <xsl:sequence select="mf:createRow('row1')"/>.
So an example of the function would be
<xsl:function name="mf:createRow">
<xsl:param name="input"/>
<fo:table-row>
<fo:table-cell padding-bottom="6pt">
<fo:block>
<xsl:value-of select="$input"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:function>
and you could call it as e.g.
<fo:table-body>
<xsl:sequence select="(1 to 3) ! ('Row ' || . ) ! mf:createRow(.)"/>
</fo:table-body>

howto set xsl fo table height to 100%?

I have created a pdf template with a table.
The table has a border; after rendering all the data, the content covers only half of the page, so the table border covers only the content.
But I want the table border to cover the entire page regardless of the height of the content, like this:
I have tried to set height of table to 100%, but no luck.
I have also tried to put block-progression-dimension.optimum="100%"
on last table cell; let me know if that's the right place
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="14pt" margin-bottom="11pt" height="100%">
<fo:table border-width="1pt" border-style="solid" height="100%" border-color="grey" margin-top="-110pt" font-family="Gotham Narrow A, Gotham Narrow B, Helvetica, Arial, sans-serif">
<fo:table-body>
<fo:table-row>
<fo:table-cell number-columns-spanned="2" margin-left="20pt">
<fo:block text-align="left" font-weight="bold" font-size="13pt" color="black" margin-bottom="2pt" margin-top="15pt" margin-left="-5pt">
${ctx.messages.repairInstructionTitle}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairInstructionMessage1}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairInstructionMessage2}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairInstructionMessage3}
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:table margin-top="10pt" margin-bottom="15pt">
<fo:table-column column-width="50%"/>
<fo:table-column column-width="50%"/>
<fo:table-body>
<fo:table-row>
#if ($ctx.orderData.deliveryAddress.country.isocode == 'US')
<fo:table-cell margin-left="30pt" number-columns-spanned="1">
<fo:block text-align="left" font-weight="bold" font-size="9pt" color="black">
${ctx.messages.repairQuestionForLocationMainland}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.mauijimIncMainland}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairDepartmentLable}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairDepartmentMainlandAddressLine1}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairDepartmentMainlandAddressLine2}
</fo:block>
</fo:table-cell>
<fo:table-cell margin-left="20pt">
<fo:block text-align="left" font-weight="bold" font-size="9pt" color="black">
${ctx.messages.repairQuestionForLocationHawaii}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.mauijimIncHawaii}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairDepartmentLable}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairDepartmentHawaiiAddressLine1}
</fo:block>
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairDepartmentHawaiiAddressLine2}
</fo:block>
</fo:table-cell>
#end
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell margin-left="15pt" block-progression-dimension.optimum="100%">
<fo:block text-align="left" font-size="13pt" color="black" font-weight="bold">
${ctx.messages.repairAnyQuestionText}
</fo:block>
#if (${ctx.orderData.deliveryAddress.country.isocode} == 'US')
<fo:block text-align="left" font-size="9pt" color="black">
${ctx.messages.repairContactInfo}
</fo:block>
#end
#if (${ctx.orderData.deliveryAddress.country.isocode} != 'US')
<fo:block text-align="left" font-size="9pt" color="black">
#set($repairContactInfo = "repairContactInfo")
#set($isocode = $ctx.orderData.deliveryAddress.country.isocode )
#set($addMessage = "$repairContactInfo$isocode")
${ctx.messages.getMessage($addMessage)}
</fo:block>
#end
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
I am not sure what effect you are trying to achieve. The height="100%" on the fo:table makes it 100% of the height of its containing block, but the fo:block has margin-bottom="11pt", which reduces the height available for the fo:block and, therefore, for the fo:table.
The height="100%" gives the table a fixed height, but the margin-top="-110pt" shifts the table up by 110pt so that I'm currently seeing 110pt of blank space after the table.
If you want something really is 100% of the page height, use height="100pvh". See https://www.antenna.co.jp/AHF/help/en/ahf-ext.html#pvh
(Also, margin-left does not apply to fo:table-cell.)
From the image of the expected output, it looks like you want to have a border around the main page region, regardless of the actual height of its content.
So, it may be enough to move the definition of the border in the fo:region-body element and remove it from the fo:table; you may also consider removing the table altogether and leaving only the blocks it contains, as it does not seem to have any function other than drawing the border.
A couple of points worth mentioning:
strictly speaking, this would not be allowed by the XSL-FO Recommendation ("The values of the padding and border-width traits must be "0"."), but is generally allowed by the formatters (AntennaHouse Formatter allows it);
this solution is easy to implement if all pages must have a border around the main region; otherwise, you have to modify your templates so that a page sequence with a bordered region-body is created for the content that needs it, and different page sequences using a page master with not borders are created for the rest of the content.

setting up dynamic row height in xsl fo

I am using below line to achive dynamic row height i.e the height should match with the left column .
But I also need to split the row into different cells ? When I am using simple fo:block-cell attrbutes ,I am not getting dynamic row hight . How can achive both dynamic row hieght and cells ??
<fo:table-row display-align="center">
<xsl:for-each select="xalan:distinct(Number)">
<fo:table-cell block-progression-dimension="auto" >
<fo:block-container height="10mm">
<fo:block font-size="9pt" border-right-width="0.1mm" border-right-style="solid" border-right-color="red" >
<xsl:value-of select="">
<xsl:variable name="">
<xsl:value-of select="">
</xsl:variable>
<xsl:if test="">
<xsl:value-of select=""/>
</xsl:if>
</fo:block>
</fo:block-container>
</fo:table-cell>
snapshot
Update -
I think one way that it could be done is to insert a vertical line after every cell value .Tried this , but somehow vertical line is not printing .
<fo:table-cell number-columns-spanned="2" xsl:use-attribute-sets="myBorder" display-align="center">
<fo:block font-size="10pt" text-align="center">
<fo:table>
<fo:table-body>
<fo:table-row>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell><!-- block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<fo:block-container>
<fo:block font-size="9pt"><!-- border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
<fo:block-container reference-orientation="90">
<fo:block>
<fo:leader leader-pattern="rule" leader-length="100%" rule-style="solid" rule-thickness="0.1mm" color="black"/>
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>
Is there anything that I am missing for vertical line insertion .
snapshot2
If you move the border and padding properties to the fo:table-cell, the border will be the full height of the cell:
<fo:table-cell border-right="0.1mm solid red">
By setting fo:block-container/#height, you're probably finding that the text in a cell can overflow the 10mm but only the 10mm is being used to determine the row height. If you remove the fo:block-container, you should get a variable-height table row.
The new code sample makes things a bit clearer: you're using 2 nested tables.
That's another complication you don't need.
Just use 1 table.
In the first column, place all the geography codes into the first cell. It does not matter how many there are: if you have 1 geography code, the cell will be one line high. If you have 16 geography codes in this cell, the cell will automatically resize to be 3 lines high.
The rest of the row contains cells with the price information. On these cells, define the right border to generate the red vertical line.
<fo:table>
<fo:table-column column-width="..mm" column-number="1"/>
<fo:table-column column-width="..mm" column-number="2"/>
...you'll have to add some code here to add the correct number of columns to your table...
<fo:table-body>
<fo:table-row>
<fo:table-cell>
...place the code to insert the country codes here....
</fo:table-cell>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center">
<fo:block-container>
<fo:block font-size="9pt">
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>

Splitting a particular column with a simple horizontal line

I am trying to split a particular column with a simple horizontal line .
<fo:table>
<fo:table-body>
<fo:table-row>
<fo:table-cell border-color="white" padding-top="5px" padding-bottom="5px">
<fo:block>
<xsl:choose>
<xsl:when test=>
<fo:block border-bottom-width="0.1mm" border-bottom-style="solid" border-bottom-color="black" font-weight="bold">
First I tried to make another table in a column for splitting of data but its not working. border-bottom inside <fo:block > is also not helping .
The line doesn't seem to properly split the column .How can I do this .
On my comment above, the best solution is change your logic to apply appropriate spanning. Here is some FO to get you thinking:
<fo:table font-size="18pt">
<fo:table-body>
<fo:table-row>
<fo:table-cell number-rows-spanned="2" border="1pt solid black" padding="3pt">
<fo:block>I am all in one spanned cell</fo:block>
</fo:table-cell>
<fo:table-cell border="1pt solid black" padding="3pt">
<fo:block>I am in top half of the cell</fo:block>
</fo:table-cell>
<fo:table-cell number-rows-spanned="2" border="1pt solid black" padding="3pt">
<fo:block>I am all in one spanned cell</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border="1pt solid black" padding="3pt">
<fo:block>I am in bottom half of the cell</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
The result is:

XSLT: Subtotals

Source XML:
<Root>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>B</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>2</Value>
</Data>
<Data>
<Code>C</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>5</Value>
</Data>
<Data>
<Code>B</Code>
<Value>4</Value>
</Data>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>C</Code>
<Value>10</Value>
</Data>
<Data>
<Code>B</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>C</Code>
<Value>5</Value>
</Data>
....
</Root>
XSL-FO Code:
My code(XSL-FO) contains 3 columns where each column contains the content of 'A', 'B', 'C'
<fo:table-body>
<xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm">
<xsl:if test="Code='A'">
<fo:table-cell>
<fo:block height="12pt">Value
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="Value" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</xsl:if>
</xfd:table-row-repeat>
</fo:table-body>
Same code for each columns to display values of 'B' & 'C'
In Table-footer i've to get these subtotal of 'A','B', 'C'
<fo:table-body>
<xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm">
<xsl:if test="Code='A'">
<fo:table-cell>
<fo:block height="12pt">SubTotal
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<--Here Sum of first 15 A's. if the A's or B's or C's exceed by 15, then the table flows to 2nd Page. In that case, 1st Page table-footer shows individual subtotals of first 15 A's, 15 B's and C's. In 2nd Page, the subtotals should contain Subtotal of first 15 A's+ Succeeding A's, in the same way B's and C's -->
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</xsl:if>
</xfd:table-row-repeat>
</fo:table-body>
Here the XSL-FO code is shown for only one column(For Root/Data/Code='A'), the other 2 columns('B' & 'C') consists of same code.
Conditions in Detail:
Condition 1): when Root/Data/Code = 'A' or 'B' or 'C'
i need individual totals of 'A', 'B' and 'C' in Table-Footer individual Column.
Condition 2): inturn if individual count(Root/Data/Code) of 'A', 'B' & 'C' crosses 15. Then Page flows to 2nd Page then Table-Footer in 2nd Page needs to contains subtotal of first 15 A's + the sum of succeeding A's in the same way for B's And C's
i.e., if 20 A's, 10 B's and 25 C's are present in Source XML.
In 1st Page, Table-Footer
SubtotalI(Value of 15 A's)=
SubtotalII(Value 10 B's)=
SubtotalIII(Value 15 C's)=
In 2nd Page, Table-Footer
SubtotalI(15 A's+ next 5 A's)=
SubtotalII(Value 10 B's)= <!--No Change as count of B's is less than 15 -->
SubtotalIII(15 C's + next 10 C's)=
I'm trying this logic using xsl:key by grouping through Code tag for evaluating sum of 'A', 'B' and 'C'. As i'm new to XSLT i'm finding it too difficult to solve this logic using xsl:key. Can anyone help in solving this logic?
Thanks in Advance
There are several difficulties with what you try to achieve. Calculating subtotals at a given point is easiest actually. You just need the preceding axis and a sum to calculate it:
sum(preceding::Value[../Code = 'A'])
To include the current value as well, use the union operator like this:
sum(Value[../Code = 'A'] | preceding::Value[../Code = 'A'])
A bigger difficulty is to show a different table 'footer' on each page. Headers and footers are repeated on pages automatically, but the contents is the same across all pages which the table spans. The only solution I see is to break the table yourself, adding a different table footer each time.
By far the easiest way is to just take a fixed number of Data elements at a time, and displaying those in a separate table. You can loop through A, B and C types in one for-each, giving each value a separate row. That way the table always has the same number of rows. You can experiment with the number you can include to determine how many fit on one page.
The following code returns a table with the first 10 Data values. A, B and C values are positioned straight under each other, but you could position them left, middle, and right respectively if you like. At the bottom of the table three rows are added with subtotals for A, B and C.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="global">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="global">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:table table-layout="fixed" width="150mm" border-style="solid">
<fo:table-column column-width="50mm"/>
<fo:table-column column-width="50mm"/>
<fo:table-column column-width="50mm"/>
<fo:table-body font-size="7pt">
<xsl:for-each select="/Root/Data[10 >= position()]">
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">
<xsl:value-of select="Code" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="Value" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:if test="position() = last()">
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">Subtotal A</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="sum(preceding::Value[../Code = 'A'] | Value[../Code = 'A'])" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">Subtotal B</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="sum(preceding::Value[../Code = 'B'] | Value[../Code = 'B'])" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">Subtotal C</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="sum(preceding::Value[../Code = 'C'] | Value[../Code = 'C'])" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:if>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
You still need something to determine how many tables of n Data items you would need, and then do some recursive calls to output all of them. Hope this is sufficient for the moment to get you going again!
PS: I noticed you are using xfd prefix. That looks like you are working with the XF Designer from Ecrion. I am not very familiar with it. The above code is a plain XSLT 1.0 solution. Not sure it works in XF Designer, please let me know..