xmlgraphics-fop-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From JBry...@s-s-t.com
Subject Re: table-layout
Date Wed, 21 Sep 2005 19:00:51 GMT
FOP only supports table-layout="fixed". If you don't mind adding some code 
to your XSL file, there's a work-around. The trick is to discover all the 
things a fixed-layout table needs to know before creating the necessary FO 
elements. Here's how:

Here's a stylesheet that determines the number of rows, determines the 
average number of characters, creates the corresponding number of columns, 
and assigns the width of each column based on the average length of 
strings in that column versus the row with the largest strings.

It's a little arcane, and it's done in XSLT 2.0. I stuck in a cell that 
spans two columns, to show that it can be done, but then I blocked 
calculating averages against such rows, as I ran out of time that I could 
dedicate to an example.

Still, it illustrates one way to work around this limitation of FOP. I do 
similar things in my stylesheets, as I sometimes have no way to know what 
an incoming table will look like.

Here's the XML source I used:

<table>
  <row>
    <cell>some text</cell>
    <cell>lots and lots and lots and lots and lots and lots and lots and 
lots of text</cell>
    <cell>more and more and more and more and more and more and more and 
more text</cell>
  </row>
  <row>
    <cell>lots and lots and lots and lots and lots and lots and lots and 
lots of text</cell>
    <cell>some text</cell>
    <cell>more and more and more and more and more and more and more and 
more text</cell>
  </row>
  <row>
    <cell span="2">lots and lots and lots and lots and lots and lots and 
lots and lots of text</cell>
    <cell>more and more and more and more and more and more and more and 
more text</cell>
  </row>
</table>

Here's the stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">

  <xsl:output method="xml" version="1.0" omit-xml-declaration="no" 
indent="yes"/>

  <xsl:template match="/">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="only" margin-top="1in" 
margin-left="1in" margin-right="1in" margin-bottom="1in">
          <fo:region-body region-name="only"/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="only">
        <fo:flow flow-name="only">
          <xsl:apply-templates/>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template> <!-- match="/" -->

  <xsl:template match="table">
    <xsl:variable name="maxColumns" select="max(for $i in row return 
count($i/*))"/>
    <xsl:variable name="cellAverages">
      <xsl:for-each select="row[1]/cell">
        <xsl:variable name="thisPosition" select="position()"/>
        <cell 
average="{string-length(string-join(/table/row[not(cell/@span)]/cell[position() 
= $thisPosition], '')) div count(/table/row/cell[position() = 
$thisPosition])}"/>
        <!-- for simplicity, don't count rows that have cells with span 
attributes -->
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="rowCounts">
      <xsl:for-each select="row">
        <row charCount="{string-length(string-join(cell, ''))}"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="longestRow" 
select="max($rowCounts/row/@charCount)"/>
    <fo:table table-layout="fixed" border-width="1pt" border-style="solid" 
border-color="black">
      <xsl:for-each select="1 to $maxColumns">
        <xsl:variable name="thisnum" select="number(.)"/>
        <fo:table-column column-width="{6.5 * 
$cellAverages/cell[$thisnum]/@average div $longestRow}in"/>
      </xsl:for-each>
      <fo:table-body>
        <xsl:apply-templates/>
      </fo:table-body>
    </fo:table>
  </xsl:template> <!-- match="table" -->

  <xsl:template match="row">
    <fo:table-row>
      <xsl:apply-templates/>
    </fo:table-row>
  </xsl:template> <!-- match="row" -->

  <xsl:template match="cell">
    <fo:table-cell padding="2pt" border-width="1pt" border-style="solid" 
border-color="black">
      <xsl:if test="@span">
        <xsl:attribute name="number-columns-spanned" select="@span"/>
      </xsl:if>
      <fo:block><xsl:apply-templates/></fo:block>
    </fo:table-cell>
  </xsl:template> <!-- match="cell" -->


</xsl:stylesheet>

And here's the output from Saxon 8 (ready to be run through FOP):

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="only" margin-top="1in" 
margin-left="1in" margin-right="1in"
                             margin-bottom="1in">
         <fo:region-body region-name="only"/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-reference="only">
      <fo:flow flow-name="only">
         <fo:table table-layout="fixed" border-width="1pt" 
border-style="solid"
                   border-color="black">
            <fo:table-column column-width="1.1666666666666667in"/>
            <fo:table-column column-width="1.1666666666666667in"/>
            <fo:table-column column-width="3in"/>
            <fo:table-body>
                  <fo:table-row>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black">
                     <fo:block>some text</fo:block>
                  </fo:table-cell>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black">
                     <fo:block>lots and lots and lots and lots and lots 
and lots and lots and lots of text</fo:block>
                  </fo:table-cell>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black">
                     <fo:block>more and more and more and more and more 
and more and more and more text</fo:block>
                  </fo:table-cell>
                  </fo:table-row>
                  <fo:table-row>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black">
                     <fo:block>lots and lots and lots and lots and lots 
and lots and lots and lots of text</fo:block>
                  </fo:table-cell>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black">
                     <fo:block>some text</fo:block>
                  </fo:table-cell>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black">
                     <fo:block>more and more and more and more and more 
and more and more and more text</fo:block>
                  </fo:table-cell>
                  </fo:table-row>
                  <fo:table-row>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black"
                                 number-columns-spanned="2">
                     <fo:block>lots and lots and lots and lots and lots 
and lots and lots and lots of text</fo:block>
                  </fo:table-cell>
                       <fo:table-cell padding="2pt" border-width="1pt" 
border-style="solid" border-color="black">
                     <fo:block>more and more and more and more and more 
and more and more and more text</fo:block>
                  </fo:table-cell>
                  </fo:table-row>
             </fo:table-body>
         </fo:table>
      </fo:flow>
   </fo:page-sequence>
</fo:root>

(I tested that and got the PDF I expected.)

It may be more of a solution than it's worth, and it may be too arcane to 
be something many people would want to maintain, but I thought I'd post it 
to show that one can get around most of FOP's limitations with XSLT.

Jay Bryant
Bryant Communication Services
(presently consulting at Synergistic Solution Technologies)




Guzandrov Andriy <andriy@pict.lviv.ua> 
09/21/2005 03:28 AM
Please respond to
fop-users@xmlgraphics.apache.org


To
fop-user@xml.apache.org
cc

Subject
table-layout






Hello,

I have a question concerning FOP support of the
table-layout="auto". Does
FOP support this property?

I use FOP 0.20.5 to convert dynamically created xml file to
PDF. I don`t know in advance how much columns will be in the
xml table, and how wide columns will be. I use this property
to build dynamic fo table but it doesn`t work properly,
though there are no errors in the log. The table space
simply is distributed equally among columns with no respect
of the text width in those.

I`ve been googling for a couple of days and still have no
clear answer on my question. Some people wrote that this
property is not supported but it was FOP 0.20.4. So how it
is with 0.20.5??? Or how one can build dynamic table under
condiotions I have?

Thanks in advance,

A.






---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Mime
View raw message