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 <[EMAIL PROTECTED]>
09/21/2005 03:28 AM
Please respond to
[email protected]
To
[email protected]
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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]