Creating footnotes in jasper-reports has 2 major challenges if you are not willing to post elaborate the result (which also is not simple):
On which page will the textField start/end when it overflows?
Only by grouping or using different detail bands are you able to easily have information on which page the textField
will start.
The pageFooter
is fixed size (it can not scale dynamically)
You need to pre-define the space that the footnotes will have, in some limited situations you can use groupFooter bands that can dynamically scale but those situations are limited.
Considering this there is no "ultimate" solution to handle footnotes, I will show one to give an idea of what can be done in a simple case scenario.
Our limitation is that a footnote relative to a textField will be on
the page that textField starts on, furthermore the height of the
pageFooter will only allow maximum 3 footnotes x page (that's my predefined space). Do note that it would
be easy to have footnote on page where textFields end by adding faking
textField in new detail band.
The idea is to use a simple JRScriplet
that will collect data when printWhenExpression
on textField is called (it may be called several times so we need to handle this). In pageFooter
we will request the data collected to generate our footnote list.
Example
JRScriplet, we will call addFootnote
to add a note and getFootnoteDatasource
to print our current footnotes.
public class FootnoteScriplet extends JRDefaultScriptlet {
//Distinct ordered values (since jasper may call more then once)
private TreeSet<String> footNotes;
public FootnoteScriplet(){
super();
this.footNotes = new TreeSet<>();
}
/**
* Add a footnote
* @param footNote, string of footNote
* @return always <code>true</true> since we use in printWhenExpression
*/
public boolean addFootnote(String footNote){
this.footNotes.add(footNote);
return true;
}
/**
* Get the datasource for footNotes and clear for future use.
* @return
*/
public JRDataSource getFootnoteDatasource(){
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(new ArrayList<>(footNotes));
this.footNotes.clear();
return ds;
}
}
jrxml, run with OnEmptyRecord datasource to test, the structure is to use multiple detail band, call our scriplet in textField's printWhenExpression
(that always return true
) to add footnote and then use a jr:list
component to display the collected footnotes in the pageFooter
.
<?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="Footnotes" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" scriptletClass="my.package.FootnoteScriplet" uuid="b5b15f62-e36a-4c91-a871-ea43faa7d0af">
<subDataset name="footNoteDS" uuid="884dba42-5c44-4049-a50a-b7e13cc47607">
<queryString>
<![CDATA[]]>
</queryString>
<field name="_THIS" class="java.lang.String"/>
</subDataset>
<parameter name="TEXT" class="java.lang.String">
<defaultValueExpression><![CDATA["Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"]]></defaultValueExpression>
</parameter>
<queryString>
<![CDATA[]]>
</queryString>
<group name="TEXT2" footerPosition="CollateAtBottom">
<groupExpression><![CDATA["2"]]></groupExpression>
</group>
<detail>
<band height="50">
<textField isStretchWithOverflow="true">
<reportElement x="0" y="0" width="550" height="16" isRemoveLineWhenBlank="true" uuid="8def1808-b5c0-45b6-943f-8a88ec04f02b">
<printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 1")]]></printWhenExpression>
</reportElement>
<textElement>
<font size="12"/>
</textElement>
<textFieldExpression><![CDATA["(1)" + $P{TEXT} + "\n" + $P{TEXT}]]></textFieldExpression>
</textField>
</band>
<band height="50">
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="b6faedf8-11d8-45c8-ac46-e3fb95106140">
<printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 2")]]></printWhenExpression>
</reportElement>
<textElement>
<font size="12"/>
</textElement>
<textFieldExpression><![CDATA["(2)" + $P{TEXT} + "\n" + $P{TEXT}]]></textFieldExpression>
</textField>
</band>
<band height="50">
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="2db72e84-3e07-4e38-b2bb-c172bbd30956">
<printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 3")]]></printWhenExpression>
</reportElement>
<textElement>
<font size="12"/>
</textElement>
<textFieldExpression><![CDATA["(3)" + $P{TEXT} + "\n" + $P{TEXT}]]></textFieldExpression>
</textField>
</band>
<band height="50">
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="4e4b4f2f-4279-4c21-8f0d-62ba92760edd">
<printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 4")]]></printWhenExpression>
</reportElement>
<textElement>
<font size="12"/>
</textElement>
<textFieldExpression><![CDATA["(4)" + $P{TEXT} + "\n" + $P{TEXT}]]></textFieldExpression>
</textField>
</band>
<band height="50">
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="5552de59-29f3-49e7-87aa-ee75b811739d">
<property name="footNote" value=""FootNote 5""/>
<printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 5")]]></printWhenExpression>
</reportElement>
<textElement>
<font size="12"/>
</textElement>
<textFieldExpression><![CDATA["(5)" + $P{TEXT} + "\n" + $P{TEXT}]]></textFieldExpression>
</textField>
</band>
</detail>
<pageFooter>
<band height="64">
<line>
<reportElement x="13" y="5" width="534" height="1" uuid="c5b242d5-cafa-43ed-9536-391a4728edf6"/>
<graphicElement>
<pen lineWidth="0.25" lineStyle="Solid"/>
</graphicElement>
</line>
<componentElement>
<reportElement positionType="Float" x="11" y="10" width="470" height="16" uuid="08bbac11-4f61-4858-8d82-639875dfe1c7"/>
<jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
<datasetRun subDataset="footNoteDS" uuid="c10d3aaf-8109-4f5b-8099-40450ea9ad7e">
<dataSourceExpression><![CDATA[$P{REPORT_SCRIPTLET}.getFootnoteDatasource()]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="16" width="470">
<textField>
<reportElement x="0" y="0" width="470" height="16" uuid="d6b5f278-02eb-43d0-934e-5282d37950f5"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{_THIS}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
<textField>
<reportElement positionType="FixRelativeToBottom" x="500" y="44" width="50" height="20" uuid="7e4a61be-7f67-4003-bd6e-1417cd77378b"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA["P." + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</pageFooter>
</jasperReport>
Output

This is far from the ultimate solution, instead the answer wants to demonstrate the problems related to footnotes and give an initial idea how to handle them.