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

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')" />

Related

How to write text diagonally on a image using XSL FO

I have a text written on a certificate document which is an image, but I am trying to write the text diagonally on the image. I am unable to change it even after changing the reference orientation of the container within which the text is present.
<xsl:template match="graphicBack">
<fo:block absolute-position="absolute">
<fo:block-container position="absolute">
<fo:external-graphic xmlns:fo="http://www.w3.org/1999/XSL/Format" scaling="uniform" content-width="210mm" content-height="296.99mm">
<xsl:attribute name="src" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:value-of select="var" />
</xsl:attribute>
</fo:external-graphic>
</fo:block-container>
<fo:block-container absolute-position="absolute" left="20mm" top="200mm">
<fo:block color="#CC6133" font-family="Courier" font-style="normal" display-align="center" font-size="300px">
COPY
</fo:block>
</fo:block-container>
</fo:block>
</xsl:template>
If you are using AH Formatter, then you can use axf:transform and axf:transform-origin (see https://www.antennahouse.com/product/ahf66/ahf-ext.html#transformation) to rotate the block to an arbitrary angle.
See the 'Block transformation' example in the "Comprehensive XSL-FO Tutorials and Samples Collection" at https://www.antennahouse.com/comprehensive-xsl-fo-tutorials-and-samples-collection/.

XSL-FO 2.0: Prevent page-break inside table

I can't find a way to prevent a page break inside a table in the RTF output.
I've tried a lot of combinations of keep-together / keep-with-next but nothing worked for me. The actual version has a parent fo:block with the attribute keep-together.within-page="always" including the whole table.
The problem only occurs when a RTF is generated. The PDF is correct and no page break inside a table exists. The table has a header-row and 3 data-rows. In the RTF there is a page-break after the header-row and the first 2 data-rows. On the next page the header is repeated and the last data-row is generated.
It's very important that the tables don't include a page-break.
Here is the relevant XSLT-Stylesheet code:
<fo:block keep-together.within-page="always" >
<xsl:for-each select="block">
<xsl:call-template name="drawData"></xsl:call-template>
</xsl:for-each>
<fo:table text-align="center">
<xsl:for-each select="row[#type='declare'][1]/column">
<fo:table-column column-number="position()" border-style="solid" border-color="#000000" border-width="0.5pt">
<xsl:attribute name="column-width"><xsl:value-of select="#width"/></xsl:attribute>
</fo:table-column>
</xsl:for-each>
<xsl:if test="row[#type='header']">
<fo:table-header>
<fo:table-row keep-together.within-page="2" background-color="#0000FF" color="#FFFFFF">
<xsl:for-each select="row[#type='header'][1]/column/block">
<fo:table-cell border-style="solid" border-color="#000000" border-width="0.5pt">
<xsl:attribute name="number-columns-spanned">
<xsl:value-of select="count(../../../row[#type='declare']/column) div count(../../../row[#type='declare'])"/>
</xsl:attribute>
<xsl:call-template name="drawData"></xsl:call-template>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</fo:table-header>
</xsl:if>
<fo:table-body>
<xsl:for-each select="row[not(#type='header')]">
<fo:table-row keep-together.within-page="2">
<xsl:for-each select="column/block">
<fo:table-cell border-style="solid" border-color="#000000" border-width="0.5pt">
<xsl:call-template name="drawData"></xsl:call-template>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
A screenshot of the relevant table:
At the moment (FOP version 2.1), the RTF output has a few limitations compared to the PDF output; in particular, it does not support keep properties.
The linked page states that
RTF output is currently unmaintained
and keeps are
supported by the RTF library but not tied into the RTFHandler
so, while it is probably unlikely that this feature will be fixed in future versions without external help, it could be relatively easy to implement it (in which case it would be a good idea to submit a patch).

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

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>

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>

XSL-FO- Specifying conditional visibility

I have an HTML table that varies according to its content. 1-3 columns hide. 1 column name changes. All depending on content.
I am creating a PDF version of this HTML table. The PDF version uses apache-FOP with fop v1.0. The PDF output contains 2 of the aforementioned tables on one page. I do not want to create an .xsl for every combination of possibilities. That's a lot of duplication and maintenance.
I can solve the column name change simply by passing the column name in with the XML content. But, conditional visibility of the columns seems to be a far more challenging task.
How can I setup conditional visibility? Is it possible?
I'm having difficulty just getting <fo:table-column visibility="collapse" /> to work. The data still displays with visility set to hidden or collapse. display="none" looked promising. But, the API doesn't show it as a valid property for a table-column.
If I can't conditionally hide a column then I'll need to produce 18 unique xsl files...
Currently, my tables are very basic. I do
<fo:block font-size="10pt">
<fo:table table-layout="fixed" width="100%" border-collapse="separate">
<fo:table-column />
<fo:table-column />
<fo:table-column />
<fo:table-column />
<fo:table-column />
<fo:table-column visibility="collapse" />
<fo:table-column />
<fo:table-column />
<fo:table-column />
<fo:table-column />
<fo:table-header>
<fo:table-cell border-width="0.2mm" border-style="solid">
<fo:block>Header 1</fo:block>
</fo:table-cell>
//...9 other headers (these should show/hide as needed)
</fo:table-header>
<fo:table-body>
<xsl:for-each select="Object/type/SomeItem/ProcedureItemCollection">
<fo:table-row>
<fo:table-cell border-width="0.2mm" border-style="solid" >
<fo:block>
<xsl:value-of select="content1"/>
</fo:block>
</fo:table-cell>
//...9 other cells...
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
XML
<Procedure>
<SiteName>Site1</SiteName>//If Site1, don't create column 2
//If Site2, don't create column 2,3,4
//If Site3, create all columns
<itemtype1>
<item><member1></member1><member2></member2></item>
<item><member1></member1><member2></member2></item>
</itemtype1>
<itemtype2>
<item><member1></member1><member2></member2></item>
<item><member1></member1><member2></member2></item>
</itemtype2>
</Procedure>
Doing it this way, I have little flexibility in creating the table. But, this is all I know how to do.
After a lot of tinkering it turns out that I can add/remove columns using xsl:when and a variable.
First create a variable
<xsl:variable name="SiteName" select="Procedure/SiteName" />
Then conditionally create the 3 elements of the table (column definition, header, body). Starting with the column definition...
<xsl:choose>
<xsl:when test="$SiteName = 'Site1'">
<fo:table-column />//column 2
</xsl:when>
</xsl:choose>
Then the header
<xsl:choose>
<xsl:when test="$SiteName = 'Site1'">
<fo:table-cell border-width="0.2mm" border-style="solid">
<fo:block>Column2</fo:block>
</fo:table-cell>
</xsl:when>
</xsl:choose>
Finally, the body
<xsl:choose>
<xsl:when test="$SiteName = 'Site1'">
<fo:table-cell border-width="0.2mm" border-style="solid" >
<fo:block>
<xsl:value-of select="column2value"/>
</fo:block>
</fo:table-cell>
</xsl:when>
</xsl:choose>