Reputation: 631
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?
Upvotes: 11
Views: 15052
Reputation: 20464
Unfortunately @emecheon answer doesn't work with current jasper version ( I use 6.7.0
), but cure is pretty much the same.
I change columnFooterOffsetY
after first page.
This way you can have footer of different size for each page.
public class CustomVerticalFiller extends JRVerticalFiller {
private int pageNumber = 0;
public CustomVerticalFiller(JasperReportsContext jasperReportsContext, JasperReport jasperReport) throws JRException {
super(jasperReportsContext, jasperReport);
}
@Override
protected void addPage(JRPrintPage page) {
super.addPage(page);
pageNumber++;
if (pageNumber == 2) {
columnFooterOffsetY += pageFooter.getHeight();
}
}
}
Upvotes: 3
Reputation: 309
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>);
Upvotes: 6
Reputation: 119
The expression I use to print a footer only on the first page is the following:
In the Print When Expression field
IF($V{PAGE_NUMBER}.intValue()==1,TRUE( ),FALSE( ))
It checks whether this is the first page and if so it returns true and prints the band. If not, it does not print anything.
If you would like to print one footer on the first page and a different one on the following pages. I use this code as the expression for the subreport properties. (not print when expression)
IF($V{PAGE_NUMBER}.intValue()==1,"subreportFooter1.jasper","subreportFooter2.jasper")
Upvotes: 0
Reputation: 51
You should put this code on Band Properties Print when expression of PageFooter
new Boolean( $V{PAGE_NUMBER}.intValue() == 1 )
Upvotes: 3