Jasper Reports: page x of y within one record - jasper-reports

I have report with multiple records, where one record is consisting of 1-5 pages. How to display "page x of y", where x is a number of page for actual record and y is total pages for actual record ? I have something like below for x variable (reset on new record, incremet by page), but it doesn't work (on each page x have 1 value):
<variable name="x" class="java.lang.Integer" resetType="Group" resetGroup="report_count" incrementType="Page" calculation="Count">
<variableExpression><![CDATA[1]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(1)]]></initialValueExpression>
</variable>
<!-- group by record -->
<group name="report_count" isStartNewPage="true">
<groupExpression><![CDATA[$V{REPORT_COUNT}]]></groupExpression>
</group>
<textField evaluationTime="Now" evaluationGroup="report_count">
<reportElement x="141" y="5" width="156" height="20"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA["Page "+$V{x}+" of"]]></textFieldExpression>
</textField>

The problem is that calculation="count" does not do what you are expecting it to. It returns the count of non-null values that your variableExpression returns. As your variableExpression only returns a single value, the variable is always set to 1.
An easy solution is to set the calculation type to "Nothing", and the variableExpression to $V{x}+1
i.e:
<variable name="x" class="java.lang.Integer" resetType="Group" resetGroup="report_count" incrementType="Page" calculation="Nothing">
<variableExpression><![CDATA[$V{x} + 1]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(1)]]></initialValueExpression>
</variable>
Edit: Alternative solution
The group tag can have the attribute isResetPageNumber. When set to true it will reset the built-in variable PAGE_NUMBER at the start of every group. As you are already grouping by each record, I think this should give you the effect you are looking for.

Related

Jaspersoft studio adjust position of fields relative to height of other fields

I am trying to create a report in Jaspersoft Studio 6.15. and I hit a wall that I can't seem to break.
The thing is I need to align my Static and Text fields depending on Stretch/NoStretch of the previous one.
In my report I want to add few text fields along with their (static text)labels aligned horizontally like
ID : $F{ID}
Name: $F{Name}
Address: $F{Address}
But I'm unable to align them. This is what I tried
Position Type: float (for all static text and fields)
Stretch Type: no stretch (for all static text and fields)
Stretch With Overflow: True (for all dynamic text fields)
The image shows what I get and what I want. Moreover, my text field's content is dynamic i.e. content size could vary.
This is what I get:
This is what it should be:
I've read many forums but could not find a solution, please suggest.
Thanks
EDIT:
Now I am getting this:
Nest each static and text field pair into a frame element:
<frame>
<reportElement ... positionType="Float"/>
<staticText>
...
</staticText>
<textField isStretchWithOverflow="true">
...
</textField>
</frame>
<frame>
...
</frame>
...
If the elements are to be included in the detail section, you can also create a separate band for each pair:
<detail>
<band>
<staticText>
...
</staticText>
<textField isStretchWithOverflow="true">
...
</textField>
</band>
<band>
...
</band>
...
</detail>

Print jasper subreports one after another

I am having two subreports in jasper
subreport1: containing list of food and beverage items
subreport2: containing list of bar items
I want generate a PDF using Java, by printing two lists one after another,
but when I try this these lists are merged together like this:
fnbitem1
baritem1
fnbitem2
baritem2
fnbitem3
baritem3
but my required output is:
fnbitem1
fnbitem2
fnbitem3
baritem1
baritem2
baritem3
How to solve this issue?
I think that the placement of each subreport is incorrect, you should create 2 detail group, Detail1 and Detail2, you place subreport1 in Detail1, and subreport2 in Detail2
<detail>
<band >
<subreport>
.....
</subreport>
</band>
<band >
<subreport>
.....
</subreport>
</band>
</detail>

I want to create Variable count in JasperReport

In my report, I have two values of column "Status" are: Y/N.
I want to count "Y" in "Status".
I created a variable $V{count_y} with Variable Expression : String.valueOf($F{status})=="Y" but $V{count_y} count all record (include Y and N).
<variable name="count_y" class="java.lang.Integer" calculation="Count">
<variableExpression><![CDATA[String.valueOf($F{status})=="Y"]]></variableExpression>
</variable>
Now, how can i count?
Thanks !
Create variable like this
<field name="status" class="java.lang.String"/>
<variable name="countY" class="java.lang.Integer" calculation="Sum">
<variableExpression><![CDATA[$F{status}.equals("Y") ? 1 : 0]]></variableExpression>
</variable>
and put $V{countY} into Summary band

How to erase rows in a table if an expression is valid in iReport

I have a table in iReport with 3 fields (A, B, C). I would to print the row iff field C is not null. For example if I have 2 records in my data source:
A = first, B = second, C = third
A = up, B = down, C = NULL
the table must have only the first row.
I have tried inserting this expression in each cell (in "Print when expression" property):
!$F{C}.equals(null)
but in this way the result is that the second row is empty (but visible).
Edit: after the first answer (now erased) the columns in the table are something like:
<jr:column ...>
<jr:columnHeader ...>
<staticText>
<reportElement .../>
<text><![CDATA[ID]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell ...>
<textField isBlankWhenNull="false">
<reportElement ... isRemoveLineWhenBlank="true">
<printWhenExpression><![CDATA[$F{ID}!=null]]></printWhenExpression>
</reportElement>
<textFieldExpression><![CDATA[$F{ID}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column ...>
<jr:columnHeader ...>
<staticText>
<reportElement .../>
<text><![CDATA[CITY]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell ...>
<textField isBlankWhenNull="false">
<reportElement ... isRemoveLineWhenBlank="true">
<printWhenExpression><![CDATA[$F{ID}!=null]]></printWhenExpression>
</reportElement>
<textFieldExpression><![CDATA[$F{CITY}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
The data source is a xml file. I've tried also with isBlankWhenNull="true" but with no change. Here a screen of the result:
When you put the print when expression on the field, only the field will be removed. Hence, the space will remain. Put the same expression on the detail band and try again.
Edit:
Looking at the problem further, I've noticed there is no option to omit records (Print When Expression) at the detail level of the table element. That option doesn't exist as you can see in iReport and also in the schema definition. Furthermore, the reason isBlankWhenNull="true" isn't working is because, even though the textfield is empty, the detail row still takes up the allocated height. Also, the PrintWhenExpression you tried to modify applies to the whole table and not the row. So it doesn't seem like it is possible to do the way you were hoping.
Here I will give you these steps to solve your problem:
Update the XPath query to your dataset run property (right click > edit table datasource from table designer view) so that the records where C is null are omitted.
Choose your sub dataset and select "Use datasource expression" from Connection / Datasource expression menu.
Insert the following expression:
((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("/root[c!='']")
Good Luck.
I found another solution to this issue:
For the dataset used for the table, adding a Filter Expression, e.g. $F{dateRemoved}==null.
This way the empty rows will be removed.
Directly answering to the problem:
After using -> Print When Expression
Go just 1 inch above and check the option "Remove Line When Blank"
100% working

How can I increment a variable with value of another variable in JasperReports?

I need to make a grand total of the items I'm counting in a subReport. To do that, I think I need to add the value of that variable to another variable for each iteration, or "increment" it by that value. The subReport gets called for each group, and I get a total for that group. I need to add the variable values, rather than database columns/fields.
I'm receiving an integer returnValue from the subReport, which is itself the count of rows in the sub-report. I want to get the grand total, since that subReport is called multiple times for the different results (each for a GROUP) from my main SQL query. I want to add up all the results, but I'm getting a null value. I tried adding an operation to the subReport as a new returnValue and choosing Sum as the operation, but that also yielded a null.
<variable name="itemCount" class="java.lang.Integer" resetType="None"/>
<variable name="grandCount"
class="java.lang.Integer"
incrementType="Group"
incrementGroup="ITEM_BUNDLE">
<variableExpression><![CDATA[$V{itemCount}]]></variableExpression>
</variable>
...
<returnValue subreportVariable="countItems" toVariable="itemCount"/>
Add attribute calculation="Sum" to variable name="grandCount"
or pass grandCount to subreport as parameter
<subreportParameter name="grandCount">
<subreportParameterExpression><![CDATA[$P{grandCount}]]></subreportParameterExpression>
</subreportParameter>
in subreport declare variable countItems with initialValue of parameter grantCount
<variable name="countItems" .... >
<variableExpression><![CDATA[$P{itemCount} + $P{grandCount}]]></variableExpression>
<initialValueExpression><![CDATA[$P{grandCount}]]></initialValueExpression>
</variable>
and return
<returnValue subreportVariable="countItems" toVariable="grandCount" calculation="Sum"/>
Im not exactly shure how to write it in JRXML since i use iReport.
In iReport, i create a new Variable, with class type "Integer", and calculation type "System"
The calculation type is important here.
In the variable expression, you will need something like $V{grandCount} = $V{grandCount} + $V{itemCount}
NOTE: JasperReports render band by band, so you wont be able to use the grandCount variable in a band before the subreport band.
Hope im not too late
You might try to increment your variable (I named it totalSum) only when the band (group) is equal to the one on which the subreport is. For this you would need a field in the report to give you the current band (group).
<variable name="totalSum"
class="java.lang.Integer"
resetType="Report"
incrementType="Group"
incrementGroup="ITEM_BUNDLE"
calculation="Nothing">
<variableExpression>
<![CDATA[new Boolean($F{reportPart}.equals("The_band_with_the_subreport")).booleanValue() ? $V{returnValue} : $V{totalSum}]]>
</variableExpression>
<initialValueExpression>
<![CDATA[new Integer(0)]]>
</initialValueExpression>
</variable>
I'm not sure if this works, I don't have the context to test it. But you might also try a second solution - with three variables. For example, you keep the value returned from the subreport (let's say returnValue) in a variable and you use another two variables to hold the sum - one until the subreport is called (let's say partialSum) and the second to store the sum between the returnValue and the partialSum. Let's call it totalSum. Then you would have something like this for totalSum:
<variable name="totalSum"
class="java.lang.Integer"
resetType="Report"
incrementType="Group"
incrementGroup="ITEM_BUNDLE"
calculation="Nothing">
<variableExpression>
<![CDATA[$V{returnValue} + $V{partialSum}]]>
</variableExpression>
<initialValueExpression>
<![CDATA[new Integer(0)]]>
</initialValueExpression>
</variable>
For partialSum, you'll have something like this:
<variable name="partialSum"
class="java.lang.Integer"
resetType="Report"
calculation="Sum"
incrementType="None">
<variableExpression>
<![CDATA[new Boolean($F{reportPart}.equals("The_band_with_the_subreport")).booleanValue() ? $V{returnValue} : new Integer(0)]]>
</variableExpression>
<initialValueExpression>
<![CDATA[new Integer(0)]]>
</initialValueExpression>
</variable>
I hope this helps a bit. It would be easier to make all these settings from iRport directly on the report you want to use.