Rotated text in table cell rendered above cell not within
Asked Answered
C

3

11

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:

rotated text 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:

rotated text overlaying previous text and empty 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?

Confessional answered 16/1, 2018 at 20:57 Comment(7)
Which formatter are you using?Hock
In your XSL, count the characters for each table header and come up with a formula that sets the right height. Set it and place the content. Or if your want text to break for longer items, pick a height. The formatter is not going to guess what you wish.Cammie
@TonyGraham I'm using apache-fop.Athanasius
@KevinBrown That's for the cell height, i.e. the second problem. The main problem is the positioning of the text blocks.Athanasius
I'm facing same problem. Noticed that setting text-align on block to end/outside makes things better (text is within table cell), but it seems to be just a side-effect...Zoilazoilla
Also, setting precise width and height on fo:block-container forces text to be within table cell. But that's not a generic solution, as every table cell might have different size...Zoilazoilla
When text-intent is set to 0mm and text-align to end/outside, text is 100% within table cell, but incorrectly formated (0pt from table cell border and aligned to wrong table cell edge).Zoilazoilla
S
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.

Submarginal answered 24/1, 2018 at 13:42 Comment(0)
I
0

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

Isiahisiahi answered 2/9, 2018 at 2:32 Comment(0)
R
0

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>
Renascence answered 28/10, 2018 at 20:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.