0

I have a table coded in XSL which is used to generate a pdf when executed. There is an issue when a user enters data into the CountryGroup table cell. If there are no spaces in the data it will break the boundaries of the cell and the data will spill into other cells making the document unreadable.

I am trying to figure out a way to make the text wrap. Please see the code snippet below:

 <fo:table-cell border="1pt solid black" display-align="after"><fo:block>Customer Seq Range</fo:block></fo:table-cell>
           <fo:table-cell border="1pt solid black" display-align="after"><fo:block>Label Code</fo:block></fo:table-cell>
           <fo:table-cell border="1pt solid black" display-align="after"><fo:block>Labelled Lot</fo:block></fo:table-cell>
           <fo:table-cell border="1pt solid black" display-align="after"><fo:block>Country Group</fo:block></fo:table-cell> <!--NCCRC200003  Country Group -->
           <fo:table-cell border="1pt solid black" display-align="after"><fo:block>Lot Expiry</fo:block></fo:table-cell>
           <fo:table-cell border="1pt solid black" display-align="after"><fo:block>QTY</fo:block></fo:table-cell>
     </fo:table-row>
    </fo:table-header>
    <fo:table-body>
    <fo:table-row font-size="9pt" font-weight="normal">
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="ItemNumber"/></fo:block></fo:table-cell>
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="RangeStart"/>-<xsl:value-of select="RangeEnd"/></fo:block></fo:table-cell>
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="CustRangeStart"/>-<xsl:value-of select="CustRangeEnd"/></fo:block></fo:table-cell>
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="LabelType"/></fo:block></fo:table-cell>
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="OtherLot"/></fo:block></fo:table-cell>
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="CountryGroup"/></fo:block></fo:table-cell> <!--NCCRC200003  Country Group. -->
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="ExpiryDate"/></fo:block></fo:table-cell>
        <fo:table-cell border="1pt solid black" padding="3mm 0mm" display-align="center"><fo:block><xsl:value-of select="Quantity"/></fo:block></fo:table-cell>
    </fo:table-row> 
halfer
  • 19,824
  • 17
  • 99
  • 186
AndroidDev123
  • 280
  • 3
  • 24

1 Answers1

0

If you want a block to wrap into several lines when no spaces are present in the text, try to define the attribute wrap-option to "wrap".

If I reindent your code, you have:

<fo:table-cell border="1pt solid black" padding="3mm 0mm" 
   display-align="center">
  <fo:block>
    <xsl:value-of select="CountryGroup"/>
  </fo:block>
</fo:table-cell>

I would change the code above by:

<fo:table-cell border="1pt solid black" padding="3mm 0mm" 
   display-align="center">
  <fo:block wrap-option="wrap"><!-- added wrap-option attribute here -->
    <xsl:value-of select="CountryGroup"/>
  </fo:block>
</fo:table-cell>

More information about this here: XSL-FO fop. Long text flows into adjacent cells/block, obscuring stuff there

If this doesn't work, you can inject zero-width spaces into your block, hoping this will help to wrap your text into several lines:

<xsl:template name="string-replace-all">
  <xsl:param name="text" />
  <xsl:param name="replace" />
  <xsl:param name="by" />
  <xsl:choose>
    <xsl:when test="contains($text, $replace)">
      <xsl:value-of select="substring-before($text,$replace)" />
      <xsl:value-of select="$by" />
      <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text"
        select="substring-after($text,$replace)" />
        <xsl:with-param name="replace" select="$replace" />
        <xsl:with-param name="by" select="$by" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$text" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

This is a snippet of code I found here: XSLT 1.0: Replacing all occurences of a string in a node-set

Instead of

    <xsl:value-of select="CountryGroup"/>

You could try (edited according to suggestions below):

    <xsl:call-template name="string-replace-all">
      <xsl:with-param name="text" select="CountryGroup"/>
      <xsl:with-param name="replace" select="','"/>
      <xsl:with-param name="by" select="',&#8203;'"/>
    </xsl:call-template>

For the zero width space, I used its Unicode &#8203;. If you work with another encoding, you will need to adjust this.

Pierre François
  • 5,850
  • 1
  • 17
  • 38
  • How do i integrate that block into the middle of my table? – AndroidDev123 Mar 27 '20 at 11:13
  • Where you have `` you can put `` Since this is completely unclear, I will edit my answer above. – Pierre François Mar 27 '20 at 11:15
  • Thank you for your answer I have adjusted my code and regenerated the pdf file however it is still unfortunately breaking the boundaries of the cell – AndroidDev123 Mar 27 '20 at 11:23
  • Can you show us the output and provide the version of FOP you are using, if this is the case? – Pierre François Mar 27 '20 at 11:28
  • https://imgur.com/a/x79x0Yd I am not sure about the FOP version, this is a work related system which is developed in Jdeveloper 10.1.1 using Java and XSL files – AndroidDev123 Mar 27 '20 at 11:33
  • Oops. I see. Perhaps, you could add a zero-width space after each `,` to get this done. See my edited answer above. – Pierre François Mar 27 '20 at 11:44
  • The IDE is showing an error on this line at the /> it says its expecting ";" but of course when I add that it doesn't correct the error – AndroidDev123 Mar 27 '20 at 14:38
  • 1
    Change `",​"` to `"',​'"`. The value of the @select is an XPath expression, so you need to provide it as a string, and you need the `;` to finish the `​` numeric character reference. Your other alternative is ``, but that still needs the `;`. – Tony Graham Mar 27 '20 at 14:47
  • 1
    Is it an option to replace `,` with `, ` (i.e., add an ordinary space) just so that the output is more readable? – Tony Graham Mar 27 '20 at 14:59
  • Its to stop long strings breaking the cells in the table when displayed in a pdf. The ammendment you suggested @TonyGraham allowd the code to compile however when generating the pdf report it throws an error - : 20/03/30 15:03:40 ERROR: 'line 266: Syntax error in ','.' 20/03/30 15:03:40 FATAL ERROR: 'Could not compile stylesheet' – AndroidDev123 Mar 30 '20 at 14:06
  • `wrap-option="wrap"` is the default (see https://www.w3.org/TR/xsl11/#wrap-option), so specifying it is unlikely to change anything. If this was AH Formatter, you could use `axf:word-wrap="break-word"` (see https://www.antennahouse.com/product/ahf70/docs/ahf-ext.html#axf.word-wrap), but that would be less readable than breaking after commas. – Tony Graham Mar 31 '20 at 16:45