Reputation: 401
I'm trying to fit a multi-column table based on an XML file in a standard A4 page. The problem is that the column that exceeds the margin doesn't appear in the generated file (as expected). I want to make the outer columns appear in the next row, however I can't find any way how to do this. I tried to simply change the font size or the orientation of a page, but these solutions are simply a bypass that would fail when the number of columns were higher. Is this even possible to do this using plain XSLT 1.0? My code is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-height="29cm" page-width="21cm"
margin-bottom="2cm" margin-top="2cm" margin-left="1.5cm" margin-right="1.5cm">
<fo:region-body margin-top="1cm"/>
<fo:region-before extent="1.5cm"/>
<fo:region-after extent="1.5cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:static-content flow-name="xsl-region-before">
<fo:block>Stylistique suppliers report. Generated <xsl:value-of
select="report/statistics/dateOfGeneration"/></fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block>Page <fo:page-number/></fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:external-graphic src="logo.jpg" width="auto" height="auto"
content-height="300px"/>
</fo:block>
<fo:block linefeed-treatment="preserve">Summary table</fo:block>
<fo:table>
<xsl:for-each select="report/suppliers/supplier">
<fo:table-column column-width="30mm"/>
</xsl:for-each>
<fo:table-header>
<fo:table-row>
<xsl:for-each select="report/suppliers/supplier">
<fo:table-cell>
<fo:block font-weight="bold" width="30mm" font-size="8px">
<xsl:value-of select="name"/>
</fo:block>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<fo:table-row>
<xsl:for-each select="report/suppliers/supplier">
<fo:table-cell>
<xsl:for-each select="productList/product">
<fo:block>
<xsl:value-of select="name"/>
</fo:block>
<fo:block>
<xsl:value-of select="priceInPLN"/>
</fo:block>
</xsl:for-each>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Views: 1607
Reputation: 8068
Fake the table by using fo:block
for the table rows and fo:inline-container
(with a fixed width) for each table cell.
You may have trouble getting the 'cells' to have the same height, but what you want to do is out of scope for fo:table
.
Alternatively, if you know exactly where the table should break, you could omit the fo:table-row
and use the starts-row
and ends-row
properties on the fo:table-cell
to cause your breaks.
Since you are using XSLT 1.0 and you know the width of the table cells, you could use Muenchian Grouping (https://stackoverflow.com/search?q=muenchian) to group the appropriate number of cells per row. (This would be much simpler if you were using XSLT 2.0 or XSLT 3.0 and could use xsl:for-each-group
.)
Also, there's multiple answered SO questions about wrapping text in table cells, including:
(Wrapping text would also be simpler if you were using XSLT 2.0 or XSLT 3.0 (or using AH Formatter, FWIW). See, e.g., https://stackoverflow.com/a/33689540/4092205.)
Upvotes: 1