Search code examples
jasper-reports

How to change the fontName of a text field in a report using a parameter or field without the help of conditional styles or markup?


I create a PDF report using JasperReports that contains multiple text fields. I receive a font name as a field from a custom data source. The text fields in my report should use this font. All my text fields use the ,,Styled'' markup.

Is there a way to set the font of text field(s) after compiling the .jrxml using parameters or fields and therefore enable a different font each time that a report is generated using the .jasper?

In this answer to a question related to font size, an example is shown how one can use the ,,Styled'' markup to apply a different font size to a text field expression:

<textField>
    <reportElement x="10" y="10" width="150" height="13" />
    <textElement markup="styled"/>
    <textFieldExpression>
        <![CDATA["<style size=\"" + $V{fontSize} + "\">" + $F{name} + "</style>"]]>
    </textFieldExpression>
</textField>

I tried to adapt this using <style fontName="Arial">some text</style> in a text field expression, however, it does not seem to resolve the attribute fontName and change the font accordingly.

Looking at the reference, I am not quite sure when fontName is supported and when it is not. Since the <font> tag is located in the <textElement> in a text field (see below), does that mean that an 'inline style' in <textFieldExpression> cannot have a different fontName or better, a font at all that differs from the one defined in <textElement>?

  <textField>
    <reportElement x="0" y="350" width="150" height="40"/>
    <textElement>
      <font fontName="Monospaced" size="12" isItalic="true" isUnderline="true" pdfFontName="Courier-Oblique"/>
    </textElement>
    <text>The quick brown fox jumps over the lazy dog.</text>
  </textField>


Solution

  • Solution

    Yes, the task can be solved with help of styled markup but another solution is more elegant. It is easy to set font name and size dynamically using net.sf.jasperreports.style.fontName and net.sf.jasperreports.style.fontSize element properties.

    Working example

    In this example I used hsqldb dataadapter, JasperReports Studio (JSS) contains it out of box.

    The font properties were set with the help of a query, which means that I used fields at the properties expressions. We can also use parameters at the properties expressions.

    The jrxml:

    <?xml version="1.0" encoding="UTF-8"?>
    <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Dynamic font" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
        <property name="com.jaspersoft.studio.data.defaultdataadapter" value="Sample DB"/>
        <queryString language="SQL">
            <![CDATA[SELECT 'Arial Black' AS "fontName", '12' AS "fontSize", 'apple' AS "fruitName", 10 AS "price" FROM (VALUES(0))
    UNION
    SELECT 'Algerian' AS "fontName",  '16' AS "fontSize", 'peach' AS "fruitName", 20 AS "price" FROM (VALUES(0))]]>
        </queryString>
        <field name="fruitName" class="java.lang.String"/>
        <field name="price" class="java.lang.Integer"/>
        <field name="fontName" class="java.lang.String"/>
        <field name="fontSize" class="java.lang.String"/>
        <columnHeader>
            <band height="30" splitType="Stretch">
                <staticText>
                    <reportElement x="0" y="0" width="278" height="30"/>
                    <textElement textAlignment="Center" verticalAlignment="Middle"/>
                    <text><![CDATA[Fruit]]></text>
                </staticText>
                <staticText>
                    <reportElement x="278" y="0" width="277" height="30"/>
                    <textElement textAlignment="Center" verticalAlignment="Middle"/>
                    <text><![CDATA[Price]]></text>
                </staticText>
            </band>
        </columnHeader>
        <detail>
            <band height="30" splitType="Stretch">
                <textField>
                    <reportElement x="0" y="0" width="278" height="30">
                        <propertyExpression name="net.sf.jasperreports.style.fontName"><![CDATA[$F{fontName}]]></propertyExpression>
                        <propertyExpression name="net.sf.jasperreports.style.fontSize"><![CDATA[$F{fontSize}]]></propertyExpression>
                    </reportElement>
                    <textFieldExpression><![CDATA[$F{fruitName}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="278" y="0" width="277" height="30"/>
                    <textFieldExpression><![CDATA[$F{price}]]></textFieldExpression>
                </textField>
            </band>
        </detail>
    </jasperReport>
    

    The dataset contains two records - each value will use its own font name and size.

    The generated output

    The output was generated with help of JSS:

    enter image description here