How to display blocks in multiple rows in XSL-FO? - xslt

I am trying to add images in multiple rows.
Here is my code:
<fo:block-container reference-orientation="90" >
<xsl:for-each select="Icons/Icon">
<fo:block>
<fo:external-graphic src="{#Source}"/>
</fo:block>
</xsl:for-each>
</fo:block-container>
The <fo:block-container> is placed in an <fo:table-cell>.
You can see examples below where text is other part of the table.
How it looks:
But it should look like this:
I tried to add width for block-container, but it doesn't help.

It can't wrap because you're using a rotated fo:block-container, so what you're seeing is the rotated equivalent of blocks overflowing past the bottom of the page.
It's not clear to me why you're rotating the images, but you could put each graphic inside a separate fo:inline-container and set the reference-orientation on each. (See https://www.w3.org/TR/xsl11/#fo_inline-container)
<fo:table-cell>
<fo:block>
<fo:inline-container reference-orientation="90">
<fo:block>
<fo:external-graphic src="..." />
</fo:block>
</fo:inline-container>
...
</fo:block>
</fo:table-cell>

Related

How to shrink multi "external-graphic" inside block in XSL-FO

I created a block in a block-container. And inside the block, there will be few number of external-graphic dynamically. I expected the width of the images should not exceed the block-container width.
<fo:block-container width="90mm" display-align="center" text-align="center" margin-bottom="1mm">
<fo:block line-height="0mm">
<fo:external-graphic src="..."
content-width="scale-down-to-fit" content-height="scale-down-to-fit"
display-align="center" text-align="center"/>
<fo:external-graphic src="..."
content-width="scale-down-to-fit" content-height="scale-down-to-fit"
display-align="center" text-align="center"/>
</fo:block>
</fo:block-container>
I would have said to add content-width="scale-down-to-fit", but you already have that.
You might try removing the content-height property, since the height of the fo:block-container is not fixed.
You could also try removing both content-width and content-height and adding max-width="100%" (see https://www.w3.org/TR/xsl11/#max-width).
In my case, the trick was to combine content-height="scale-to-fit" and max-width="100%". When i removed one of them (whatever which of them), the image exceeded.
<fo:external-graphic src="..." content-height="scale-to-fit" max-width="100%" />

Image not found for background-image attribute of block-container

I have xslt template that generates pdf using Apache FOP. I have problem that background image cannot be found. I have tried absolute paths, relative paths and many else, but nothing happens. Could any of you help me ?
I have tried following paths, but it did not help.
c:/Projects/demo/src/main/resources/certificate.png is absolute path
background-image="c:/Projects/demo/src/main/resources/certificate.png"
background-image="file:///c:/Projects/demo/src/main/resources/certificate.png"
background-image="certificate.png"
background-image="./certificate.png"
background-image="url(certificate.png)"
background-image="url(./certificate.png)"
background-image="url(c:/Projects/demo/src/main/resources/certificate.png)"
background-image="url(file:///c:/Projects/demo/src/main/resources/certificate.png)"
background-image="url(file:///./certificate.png)"
<fo:block-container position="absolute" height="210mm" width="297mm"
background-image="c:/Projects/demo/src/main/resources/certificate.png"
background-position="right" background-color="transparent">
<!-- Name -->
<fo:block-container absolute-position="fixed"
top="95mm">
<fo:block
letter-spacing="8px"
font-size="22pt"
color="#333333"
font-family="BrandonBlack"
text-align="center">
<xsl:value-of select="data/user"/>
</fo:block>
</fo:block-container>
<!-- Course Name -->
<fo:block-container absolute-position="fixed"
top="135mm">
<fo:block
letter-spacing="5px"
font-size="19pt"
color="#7b5f6f"
font-family="BrandonBlack"
text-align="center">
<xsl:value-of select="data/course"/>
</fo:block>
</fo:block-container>
<!-- Date -->
<fo:block-container absolute-position="fixed"
top="189mm" left="214mm">
<fo:block
letter-spacing="2px"
font-size="12pt"
color="#333333"
font-family="BrandonBlack">
<xsl:value-of select="data/date"/>
</fo:block>
</fo:block-container>
</fo:block-container>
You need to use url() and wrap the URL in single quotes, like so:
<fo:block-container background-image="url('./certificate.png')" />

XSLT FO Horizontal alignment of inline container

I'm trying to align an inline container horizontally, but I can't find the corresponding FO attribute like display-align for vertical alignment.
Here is some example code without any alignment:
<fo:inline-container background-color="white" border-style="solid" border-width="2mm" border-color="white">
<fo:block font-family="Blablabla" text-align="center" font-size="54pt" space-after="6mm" text-indent="0mm" last-line-end-indent="0mm" alignment-baseline="central">
...
</fo:block>
</fo:inline-container>
The whole thing is going to be processed with AntennaHouse 5.2.
Thanks in advance
Stavros
Add text-align="center" to the fo:block (or similar) that contains the fo:inline-container:
<fo:block text-align="center">
<fo:inline-container background-color="white" border-style="solid" border-width="2mm" border-color="white">
<fo:block font-family="Blablabla" text-align="center" font-size="54pt" space-after="6mm" text-indent="0mm" last-line-end-indent="0mm">
...
</fo:block>
</fo:inline-container>
</fo:block>
Also, your alignment-baseline="central" doesn't do anything since alignment-baseline doesn't apply to fo:block and is not inherited. See https://www.w3.org/TR/xsl11/#alignment-baseline

setting up dynamic row height in xsl fo

I am using below line to achive dynamic row height i.e the height should match with the left column .
But I also need to split the row into different cells ? When I am using simple fo:block-cell attrbutes ,I am not getting dynamic row hight . How can achive both dynamic row hieght and cells ??
<fo:table-row display-align="center">
<xsl:for-each select="xalan:distinct(Number)">
<fo:table-cell block-progression-dimension="auto" >
<fo:block-container height="10mm">
<fo:block font-size="9pt" border-right-width="0.1mm" border-right-style="solid" border-right-color="red" >
<xsl:value-of select="">
<xsl:variable name="">
<xsl:value-of select="">
</xsl:variable>
<xsl:if test="">
<xsl:value-of select=""/>
</xsl:if>
</fo:block>
</fo:block-container>
</fo:table-cell>
snapshot
Update -
I think one way that it could be done is to insert a vertical line after every cell value .Tried this , but somehow vertical line is not printing .
<fo:table-cell number-columns-spanned="2" xsl:use-attribute-sets="myBorder" display-align="center">
<fo:block font-size="10pt" text-align="center">
<fo:table>
<fo:table-body>
<fo:table-row>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell><!-- block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<fo:block-container>
<fo:block font-size="9pt"><!-- border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
<fo:block-container reference-orientation="90">
<fo:block>
<fo:leader leader-pattern="rule" leader-length="100%" rule-style="solid" rule-thickness="0.1mm" color="black"/>
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>
Is there anything that I am missing for vertical line insertion .
snapshot2
If you move the border and padding properties to the fo:table-cell, the border will be the full height of the cell:
<fo:table-cell border-right="0.1mm solid red">
By setting fo:block-container/#height, you're probably finding that the text in a cell can overflow the 10mm but only the 10mm is being used to determine the row height. If you remove the fo:block-container, you should get a variable-height table row.
The new code sample makes things a bit clearer: you're using 2 nested tables.
That's another complication you don't need.
Just use 1 table.
In the first column, place all the geography codes into the first cell. It does not matter how many there are: if you have 1 geography code, the cell will be one line high. If you have 16 geography codes in this cell, the cell will automatically resize to be 3 lines high.
The rest of the row contains cells with the price information. On these cells, define the right border to generate the red vertical line.
<fo:table>
<fo:table-column column-width="..mm" column-number="1"/>
<fo:table-column column-width="..mm" column-number="2"/>
...you'll have to add some code here to add the correct number of columns to your table...
<fo:table-body>
<fo:table-row>
<fo:table-cell>
...place the code to insert the country codes here....
</fo:table-cell>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center">
<fo:block-container>
<fo:block font-size="9pt">
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>

Page break inside table XSL-FO

I have an XSL-FO stylesheet for a table.
<fo:page-sequence master-reference="defaultPage">
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="9pt"/>
<fo:table-column column-width="30pt"/>
<fo:table-column column-width="150pt"/>
<fo:table-header>
<fo:table-row>
<fo:table-cell>
<fo:block><xsl:text>Column 1</xsl:text></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block><xsl:text>Column 2</xsl:text></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block><xsl:text>Column 3</xsl:text></fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<fo:table-row>
<xsl:apply-templates select="rbrOcjena"/>
<xsl:apply-templates select="sifPred"/>
<xsl:apply-templates select="nazPred"/>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
The table can have many rows, so I'd like to break it on new page when it comes to the end of current, when generating PDF. Also, I would like to repeat table header on new page, if that's possible. What attributes should I put in the table tag to make it so?
Thanks!
The table can have many rows, so I'd like to break it on new page when
it comes to the end of current
Without seeing your XSL-FO code, it is difficult to answer this. Please show it. But generally, this is done with keeps and breaks. For example:
<fo:table-row keep-together.within-page="always">
I would like to repeat table header on new page, if that's possible.
What attributes should I put in the table tag to make it so?
Instructing an XSL-FO processor to repeat a number of rows at the top of every page is not done via an attribute to fo:table. Instead, the rows that are to be repeated are put inside fo:table-header:
<fo:table-header>
<fo:table-row>
<fo:table-cell>
<!--Block and text content-->
</fo:table-cell>
</fo:table-row>
</fo:table-header>
Then, the default behaviour of the processor should be to repeat the header rows after a page break. That's because the omit-header-at-break attribute of fo:table is set to "false" by default.
The most obvious reason for this is that it is immediately clear which rows belong to the header and should thus be repeated. If this was just a reference in an attribute of fo:table it would be harder to identify multiple rows as the header. You will find the relevant part of the XSL specification here.
I've faced similar scenario...
Try below code...
<fo:table-row>
<xsl:if test="position() != 1">
<xsl:attribute name="break-before">page</xsl:attribute></i>
.
.
.