ThirumalMarugan
ThirumalMarugan

Reputation: 95

XSL FO Customized Table requirement

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: enter image description here

Upvotes: 1

Views: 210

Answers (2)

Kevin Brown
Kevin Brown

Reputation: 8877

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:

enter image description here

Upvotes: 2

lfurini
lfurini

Reputation: 3788

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.

Upvotes: 1

Related Questions