I would like to have a footer appear only on the first page of jasper reports.
After searching the forums, I have seen this question asked and improperly answered several times here. As many have suggested I have tried putting a print when expression on the footer band to prevent it from printing when it isn't the first page like:
new Boolean($V{PAGE_NUMBER}.intValue() == 1)
This does not work though. The result is that none of the attributes of the page footer print, but the footer block still prints and takes up space preventing the detail from using the whole page. Effectively, you have a footer with data on the first page and a footer with no data on every following page.
Does anyone know a trick how to actually make this work?
Definitely there does not seem to be a direct way of achieving it, at least with current version of Jasper libraries available. However here's a very crude workaround that worked for us in a similar requirement. I separated out only the footer management part of the code into a sample project this morning and it works fine.
Notes:
How the example is built:
new Boolean($V{PAGE_NUMBER}.intValue() == 1
, for the page-footer band.Sample source XML used: (add additional lines to the XML so that the report wraps to multiple pages)
<?xml version="1.0" encoding="UTF-8"?>
<employees>
<employee id="1001" name="AAA" email="[email protected]" salary="20500.125"/>
<employee id="1002" name="BBB" email="[email protected]" salary="10000.500"/>
<employee id="1003" name="CCC" email="[email protected]" salary="12275.750"/>
<employee id="1004" name="DDD" email="[email protected]" salary="10750.750"/>
</employees>
JRXML created with iReport (with a printwhenexpression for the footer band):
<?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="jr_footer_display_test" pageWidth="792" pageHeight="288" orientation="Landscape" columnWidth="752" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="27ac3ae2-27da-484b-b088-b4d79aa973cc">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<queryString language="xPath">
<![CDATA[//employee]]>
</queryString>
<field name="email" class="java.lang.String">
<fieldDescription><![CDATA[./@email]]></fieldDescription>
</field>
<field name="id" class="java.lang.String">
<fieldDescription><![CDATA[./@id]]></fieldDescription>
</field>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[./@name]]></fieldDescription>
</field>
<field name="salary" class="java.lang.String">
<fieldDescription><![CDATA[./@salary]]></fieldDescription>
</field>
<background>
<band splitType="Stretch"/>
</background>
<columnHeader>
<band height="50">
<staticText>
<reportElement uuid="c3d42e71-672e-402f-9fbb-4889be2a269b" x="29" y="2" width="100" height="20"/>
<textElement/>
<text><![CDATA[ID]]></text>
</staticText>
<staticText>
<reportElement uuid="a4c42dc4-4276-485a-b5a6-b4e6bd2bc217" x="136" y="2" width="100" height="20"/>
<textElement/>
<text><![CDATA[Name]]></text>
</staticText>
<staticText>
<reportElement uuid="157e527b-7ad5-46bf-a06d-2fa0a2686b1e" x="253" y="2" width="100" height="20"/>
<textElement/>
<text><![CDATA[Email]]></text>
</staticText>
<staticText>
<reportElement uuid="4d87c542-7057-4bc1-9a7e-fbd6a554f33a" x="386" y="2" width="100" height="20"/>
<textElement/>
<text><![CDATA[Salary]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="21" splitType="Stretch">
<textField>
<reportElement uuid="31d09543-a128-469a-be38-3d8987ba781b" x="29" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
</textField>
<textField>
<reportElement uuid="ce5c11f8-68da-4efd-93fa-e1f1b5ce407f" x="136" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
<textField>
<reportElement uuid="300dcc3b-8a2a-489d-8518-7283c95b2f88" x="253" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{email}]]></textFieldExpression>
</textField>
<textField>
<reportElement uuid="a37f2df9-2459-446d-bc47-488a336aa60e" x="386" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{salary}]]></textFieldExpression>
</textField>
</band>
</detail>
<pageFooter>
<band height="40" splitType="Stretch">
<printWhenExpression><![CDATA[new Boolean($V{PAGE_NUMBER}.intValue() == 1)]]></printWhenExpression>
<textField>
<reportElement uuid="3d9beff7-69b8-44d9-af80-2962b9262368" x="29" y="12" width="80" height="20"/>
<textElement textAlignment="Left"/>
<textFieldExpression><![CDATA["Page: "+$V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</pageFooter>
</jasperReport>
Custom report-filler implementation: (this handles the height resetting logic to ensure detail band stretches longer from page 2 onwards)
public class CustomVerticalFiller extends JRVerticalFiller {
private JRFillBand detailBand = null;
private int pageNumber = -1;
protected CustomVerticalFiller(JasperReportsContext jasperReportsContext, JasperReport jasperReport) throws JRException {
super(jasperReportsContext, jasperReport);
detailBand = detailSection.getFillBands()[0];
}
// this method gets called after each detail band row is filled
protected void resolveBandBoundElements(JRFillBand band, byte evaluation) throws JRException {
if(band == detailBand) {
if((detailBand.getBreakHeight() > columnFooterOffsetY - offsetY) && (columnIndex == columnCount - 1)) {
// we have reached end of a page
pageNumber++;
// we reset the offset when we are at the end of page 2, so that jasper continues to fill data
if(pageNumber == 1) {
columnFooterOffsetY += pageFooter.getHeight();
}
}
}
}
}
And the Java code that actually uses the custom filler to export a PDF:
InputStream inputStream = new FileInputStream(new File(<my jrxml file path>));
JRDataSource dataSource = new JRXmlDataSource(new File(<my source xml file path>), "//employee");
Map parameters = new HashMap();
JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
CustomVerticalFiller customVerticalFiller = new CustomVerticalFiller(DefaultJasperReportsContext.getInstance(), jasperReport);
JasperPrint jasperPrint = customVerticalFiller.fill(parameters, dataSource);
JasperExportManager.exportReportToPdfFile(jasperPrint, <target pdf file path>);