Rotated text in table cell rendered above cell not

2019-06-15 21:41发布

问题:

I have the following template to generate a table defined:

<xsl:template name="CreateTable">
    <fo:block>
        <fo:table border-style="solid" table-layout="fixed">
            <fo:table-body>
                <fo:table-row>
                    <xsl:for-each select="Table/Head/Cell">
                        <fo:table-cell border-style="solid">
                            <fo:block><xsl:value-of select="." /></fo:block>
                        </fo:table-cell>
                    </xsl:for-each>
                </fo:table-row>
                <xsl:for-each select="Table/Row">
                    <fo:table-row>
                        <xsl:for-each select="Cell">
                            <fo:table-cell  border-style="solid">
                                <fo:block><xsl:value-of select="."/></fo:block>
                            </fo:table-cell>
                        </xsl:for-each>
                    </fo:table-row>
                </xsl:for-each>
            </fo:table-body>
        </fo:table>
    </fo:block>
    <fo:block margin-top="10pt"/>
</xsl:template>

Now I want to rotate the text in the first row by 90 degrees so it is to be read from bottom up.

The best solution I came up with is to:

  • set a reference-orientation="0" on <fo:table>:

    <fo:table border-style="solid" table-layout="fixed" reference-orientation="0">
    
  • enclose the <fo:block>...</fo:block> within the <fo:table-cell> with a <fo:block-container> rotated by 90 degrees:

    <fo:table-cell border-style="solid">
        <fo:block-container reference-orientation="90">
            <fo:block><xsl:value-of select="." /></fo:block>
        </fo:block-container>
    </fo:table-cell>
    

The text is rotate but the height of the first row is effectively 0 and the text is displayed above the table overlaying previous text:

When defining a specific height for the cells of the first row, the text is still before the table and not within the first row:

How can I position the text within the cells of the first row and have the height of the row computed automatically depending on the longest text within the row?

回答1:

Text displaying outside the table: the fo:block inside the table cell may be inheriting settings like a left margin from an enclosing block.

The cell height problem I haven't seen before, in Antennahouse Formatter you can rotate cell content and IIRC the cell will be resized appropriately.



回答2:

I had a similar issue that I was able to resolve by adding a margin-top to the block container for the header. And from what I can tell, the header cells resizes itself accordingly:

        <block-container>
                <xsl:attribute name="margin-top" select="'5em'"/>
                <xsl:attribute name="margin-bottom" select="'.75em'"/>
                <xsl:attribute name="reference-orientation" select="'90'"/>
            <block padding=".25em">
                <xsl:apply-templates select="node()"/>
            </block>
        </block-container>

Properly rotated header using @margin-top



回答3:

This is my attempt for the dynamic height. You can look for the yes a better factor...for my claims satisfied this rudimentary approach.

There are certainly much more precise and better solutions, but I think it is the right direction. Thanks to @Kevin Brown comment.

<xsl:for-each select="dischargeBudgets">
    <xsl:variable name="cell_height">
        <xsl:value-of select="string-length(.) * 2.2"/>
    </xsl:variable>
    <fo:table-cell padding="2px" height="{$cell_height}mm" width="6mm"
               text-align="end"
               border-style="solid">
        <fo:block-container reference-orientation="90">
            <fo:block white-space="nowrap">
                <xsl:value-of select="."/>
            </fo:block>
        </fo:block-container>
    </fo:table-cell>
</xsl:for-each>