JasperReports - Table of Contents Sample
Shows how table-of-contents structures could be created for the generated reports.
Main Features in This Sample
Creating Table-Of-Contents Structures
Creating Table-Of-Contents Structures
Description / Goal
How to create a table of contents with hyperlinks at the beginning of a document.
Since: 6.0.0
Other Samples
/demo/samples/book
Table Of Contents - Overview
A Table of Contens part displays element bookmarks defined in the other report parts. The part report should have the net.sf.jasperreports.print.create.bookmarks
set in order to collect bookmarks at report generation time.
The Table of Contents part needs to be evaluated after other report parts; if the part is to be printed at the beginning of the document it should have Report
evaluation (and no subsequent parts should have the same evaluation).
Report bookmarks are fed into the Table of Contents part as a data source. The name of the data source parameter is provided via a part property called net.sf.jasperreports.bookmarks.data.source.parameter
. If the part subreport directly uses the bookmarks as data source, the value of the property should be REPORT_DATA_SOURCE
.
The bookmark data source provides the following fields:
<field name="level" class="java.lang.Integer"/>
<field name="label" class="java.lang.String"/>
<field name="pageIndex" class="java.lang.Integer"/>
The part template needs to create Table of Contents entries based on these fields.
The level
field can be used to indent Table of Contents entries.
The label
fields provides the name of the bookmark and can be used to create a LocalAnchor
hyperlink to the bookmark.
The pageIndex
field is the temporary index of the page on which the bookmark is located. The page index is temporary because the pages generated by the Table of Contents part are not taken into account. When the table of contents is placed at the beginning of the document, the final page index can be displayed in the Table of Contents part by defining a text field with evaluationTime="Auto"
that adds $V{PAGE_NUMBER}
to $F{pageIndex}
.
The following are generic text fields that display a bookmark label and a page reference for the bookmark:
<element kind="textField" hyperlinkType="LocalAnchor" .../>
<expression>$F{label}</expression>
<hyperlinkAnchorExpression>$F{label}</hyperlinkAnchorExpression>
</element>
<element element kind="textField" evaluationTime="Auto" hyperlinkType="LocalPage".../>
<expression>$V{PAGE_NUMBER} + $F{pageIndex} + 1</expression>
<hyperlinkPageExpression>$V{PAGE_NUMBER} + $F{pageIndex} + 1</hyperlinkPageExpression>
</textField>
Table Of Contents - Examples
Below is an example of how to use report parts in order to create a document with Table of Contents.
In the main report (TableOfContentsReport.jrxml
) one can see the sectionType="Part"
attribute set, along with the net.sf.jasperreports.print.create.bookmarks
property and two parts defined in the report:
<jasperReport name="TableOfContentsReport" sectionType="Part" ...>
<property name="net.sf.jasperreports.print.create.bookmarks" value="true"/>
...
<group name="dummy">
<expression><![CDATA[1]] ></expression>
<groupHeader>
<part evaluationTime="Report">
<property name="net.sf.jasperreports.bookmarks.data.source.parameter" value="REPORT_DATA_SOURCE"/>
<partNameExpression><![CDATA["Table of Contents"]] ></partNameExpression>
<component kind="subreportPart" usingCache="true">
<expression><![CDATA["TocPart.jasper"]] ></expression>
<parameter name="ReportTitle">
<expression><![CDATA[$P{ReportTitle}]] ></expression>
</parameter>
</component>
</part>
<part>
<partNameExpression><![CDATA["Countries"]] ></partNameExpression>
<component kind="subreportPart" usingCache="true">
<expression><![CDATA["TablePart.jasper"]] ></expression>
<parameter name="REPORT_CONNECTION">
<expression><![CDATA[$P{REPORT_CONNECTION}]] ></expression>
</parameter>
<parameter name="ReportTitle">
<expression><![CDATA[$P{ReportTitle}]] ></expression>
</parameter>
</component>
</part>
</groupHeader>
</group>
</jasperReport>
The first part in the report is the Table of Contents based on TocPart.jasper
which can be obtained from the TocPart.jrxml
file. One can see how the built-in data source containing necessary bookmark data is referred using a part property:
<property name="net.sf.jasperreports.bookmarks.data.source.parameter" value="REPORT_DATA_SOURCE"/>
The TocPart.jrxml
report is a band-based report that declares 3 specific fields related to the built-in data source, and provides an appropriate design layout for the table of contents:
<jasperReport ...>
...
<field name="level" class="java.lang.Integer"/>
<field name="label" class="java.lang.String"/>
<field name="pageIndex" class="java.lang.Integer"/>
...
<title>
<band ...>
...
</band>
</title>
<pageHeader>
<band ...>
...
</band>
</pageHeader>
<detail>
<band ...>
...
</band>
</detail>
</jasperReport>
The second part in the main report is based on TablePart.jasper which can be obtained from the TablePart.jrxml
file. Here we have a table containing shipping orders from various customers, grouped by contries starting with the same letter. Bookmarks and bookmark levels are important in this report, because the table of content is built based on these bookmarks:
<jasperReport ...>
...
<group name="FirstLetterGroup" minHeightToStartNewPage="60">
<expression><![CDATA[$V{FirstLetter}]] ></expression>
<groupHeader>
<band height="25">
...
<element kind="textField" ... bookmarkLevel="1">
<expression><![CDATA[$V{FirstLetter}]] ></expression>
<anchorNameExpression><![CDATA["Letter " + $V{FirstLetter}]] ></anchorNameExpression>
</element>
</band>
</groupHeader>
</group>
<group name="ShipCountryGroup" minHeightToStartNewPage="60">
<groupExpression><![CDATA[$F{ShipCountry}]] ></groupExpression>
<groupHeader>
<band height="20">
...
<element kind="textField" y="4" width="515" height="15" bookmarkLevel="2" style="Sans_Bold">
<expression><![CDATA[" " + String.valueOf($V{ShipCountryNumber}) + ". " + String.valueOf($F{ShipCountry})]] ></expression>
<anchorNameExpression><![CDATA[$F{ShipCountry}]] ></anchorNameExpression>
</element>
</band>
</groupHeader>
<groupFooter>
...
</groupFooter>
</group>
<pageHeader>
<band ...>
...
</band>
</pageHeader>
<detail>
<band ...>
...
</band>
</detail>
<pageFooter>
<band ...>
...
<element kind="textField" y="20" width="515" height="15" hTextAlign="Center" evaluationTime="Master">
<expression><![CDATA["Page " + $V{MASTER_CURRENT_PAGE} + " of " + $V{MASTER_TOTAL_PAGES}]] ></expression>
</element>
</pageFooter>
</jasperReport>
One can see also an example of special MASTER_CURRENT_PAGE
and MASTER_TOTAL_PAGES
variables usage, along with the new evaluationTime type Master
.
Running the Sample
Running the sample requires the Apache Maven library. Make sure that maven
is already installed on your system (version 3.6 or later).
In a command prompt/terminal window set the current folder to demo/hsqldb
within the JasperReports source project and run the following command:
> mvn exec:java
This will start the HSQLDB
server shipped with the JasperReports distribution package. Let this terminal running the HSQLDB
server.
Open a new command prompt/terminal window and set the current folder to demo/samples/tableofcontents
within the JasperReports source project and run the following command:
> mvn clean compile exec:exec@all
This will generate all supported document types containing the sample report in the demo/samples/tableofcontents/target/reports
directory.