Reputation: 3263
In JasperReports, I like to render page numbers in the style current-page / total-pages .
Studying the official demos you can find the following solution using three TextFields
(because there is no built-in variable
for number of pages )
<!-- Right aligned current page -->
<textField>
<reportElement x="100" width="40" .../>
<textElement textAlignment="Right" ... />
<textFieldExpression class="java.lang.String">
<![CDATA[String.valueOf($V{PAGE_NUMBER})]]>
</textFieldExpression>
</textField>
<!-- Centered aligned slash -->
<staticText>
<reportElement x="140" width="5" .../>
<textElement textAlignment="Center" ... />
<text>
<![CDATA[/]]>
</text>
</staticText>
<!-- Left aligned total number pages (evaluationTime="Reports") -->
<textField evaluationTime="Report">
<reportElement x="145" width="40"/>
<textElement textAlignment="Left" ... />
<textFieldExpression class="java.lang.String">
<![CDATA[String.valueOf($V{PAGE_NUMBER})]]>
</textFieldExpression>
</textField>
However, this only works fine when the complete paging information is centered with respect to the page (with the slash in the middle). What I like to achieve is to right-align the whole group in a way that the total-pages has a constant distance to the right border.
How to achieve this?
Upvotes: 4
Views: 4831
Reputation: 1
What worked for me was using the evaluation time "master" along with the variables master_current_page and master_total_page.
<textField evaluationTime="Master">
<reportElement x="463" y="15" width="90" height="15" uuid="8429b168-48fe-4ba3-b0e7-86e4f25ce81f">
<property name="com.jaspersoft.studio.unit.height" value="px"/>
</reportElement>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA["PÁG" + $V{MASTER_CURRENT_PAGE} + "/ " + $V{MASTER_TOTAL_PAGES}]]></textFieldExpression>
</textField>
Upvotes: 0
Reputation: 29
I've found a solution at http://jasperforge.org/plugins/espforum/view.php?group_id=102&forumid=103&topicid=68429.
The secret seems to be that you define evalutionTime="Auto"
in your text field Page {X} of {Y}
.
Here's how it worked for me (again credit to http://jasperforge.org/plugins/espforum/view.php?group_id=102&forumid=103&topicid=68429)
First define the variable CURRENT_PAGE_NUMBER
Variable class: java.lang.Integer
Calculation: Nothing
Reset type: Page
Variable Expression: $V{PAGE_NUMBER}
This simply copies the page number. (Interestingly the forum post said that one should set Reset type: None
which works in case you want to display Page {X} of {Y}
in a detail band but does not work if you like me want it to be shown in the page header band.)
After this you should place a text field where you want your Page {X} of {Y}
to be – in my case right side of the page header, enter the expression:
msg("Page {0} of {1}", $V{CURRENT_PAGE_NUMBER}, $V{PAGE_NUMBER})
and set
evaluationTime="Auto"
Since you now have both the current as well as the total number of pages in one text field, you can easily align it in any way you like.
Upvotes: 2
Reputation: 9390
It's a harder problem that it seems at first. The key issue becomes clear when you try to be more precise about this claim, "there is no built-in variable for number of pages". All variables have an evaluation time. So the variable $V{PAGE_NUMBER}
really is a built-in variable for the number of pages... but only when it is evaluated at report time.
Therefore your Total Pages field must be evaluated at Report Time
.
Likewise, the very same variable $V{PAGE_NUMBER}
really is a built-in variable for the current page number... but only when evaluated at Now
or Page
(or other appropriate time).
Therefore your Current Page field must be evaluated Now
or Page
.
Therefore these variables must be in different Text Fields so they can be evaluated at different times.
But this conflicts with your requirement. Since you cannot put these into the same text field, you cannot have the right-most item right-justified AND have the item to its left flow perfectly into it.
Depending on your exact situation you might be able to achieve acceptable workarounds. But my guess is that the effort involved in a workaround will be too high. You could imagine, for example, a scriptlet that runs after the report is finished filling. It could parse through the report to find the field "Page 3 of xxx" and replace xxx with the correct total. I'm not sure exactly how this would work; it sounds mostly like bad news. I don't recommend it.
Or maybe you could calculate the total number of pages somehow externally and pass this in to the report as a parameter. It would work if the number of pages depends directly on the number of rows, for example. But this could only work in very specially defined cases. It's a hack.
You should certainly log an enhancement request. I could imagine a special variable that does what you want when placed into a text field which evaluates at the magical time Auto
. But for now I don't see any easy way to get what you want.
Upvotes: 5