How to get current page number and total pages as variables on each page? [duplicate] - jasper-reports

This question already has answers here:
Jasper Reports Show "Page X of Y" using a single text field
(8 answers)
Closed 4 years ago.
I need to generate OMR code on a report. I think about calling some service method on each page that get page number and total pages as parameters. Problem is: How to get that values (page number, total pages) as variables on each page ?
<background>
<band height="797">
<textField>
<reportElement x="30" y="684" width="100" height="97"/>
<textFieldExpression><![CDATA[OMRService.generateCode($V{totalPages},$V{pageNumber})]]></textFieldExpression>
</textField>
</band>
</background>

below you have sample code how to do it in 2 different textFields.
<textField evaluationTime="Page">
<reportElement x="0" y="0" width="520" height="15"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}+"/"]]> </textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="521" y="0" width="14" height="15"/>
<textElement textAlignment="Left"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
When evaluationTime="Page" you will get page number, when "Report" there will be displayed total number of pages. I dont know how to merge it together in one textfield (dont even know if its possible - I spent a lot of time on it and couldnt solve this problem).

Select the text field.
Set Expression to: msg("Page {0} of {1}", $V{V_CURRENT_PAGE_NUMBER}, $V{PAGE_NUMBER})
Set Evalutation Time to: Auto

Related

Dynamic content in text field in JRXML file

Below is the code snippet
<staticText>
<reportElement key="staticText-2" mode="Opaque" x="381" y="242" width="79" height="18" forecolor="#000000" backcolor="#FFFFFF" uuid="4ec23e25-c8d9-4941-bd81-777aff6c08a7">
<reportElement/>
<text><![CDATA[14.01.2019]]></text>
</staticText>
Each month we need to change the date in JRXML file manually <text><![CDATA[14.01.2019]]></text> as 14.11,14,12 etc.
How can I automate this feature? Like code will read the current system date, once it reaches 14th of the month , automatically the date will change in jrxml file as well?
Please help.
You could turn the staticText into a textField where you could use an expression based on JasperReports built-in date/time functions, like so:
<textField>
<reportElement key="staticText-2" mode="Opaque" x="381" y="242" width="79" height="18" forecolor="#000000" backcolor="#FFFFFF" uuid="4ec23e25-c8d9-4941-bd81-777aff6c08a7"/>
<textFieldExpression><![CDATA[DATEFORMAT(EDATE($P{AccountingDate}, 1), "14.MM.yyyy")]]></textFieldExpression>
</textField>

Text truncated on JasperReports

I have a JasperReports's report within an application that is truncating text and I am unsure how to get it to display the full name.
The code snippet below shows that I have included isStretchWithOverflow="true":
<textField isStretchWithOverflow="true" isBlankWhenNull="true">
<reportElement x="353" y="0" width="79" height="30"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{acname}]]></textFieldExpression>
</textField>
The JasperReports's image shows incorrect values. One of these should read: 'Double Time Pay - Bill Regular' and the other 'Double Time Pay - Bill Overtime'.

Comparing two columns on a row and removing if they match

I'm looking to create a report in iReport, this will display a row of Car weights which includes there expected weight and actual weight. I'm looking to only display the cars that have are different between the actual weight and expected weight. I'm also looking to display an extra columns on the right which displays how much they're different by.
E.g.
CAR Expected Weight ActualWeight WeightDIFF
-------------------------------------------
> NUGLN9L 2000kg 2200kg 200kg
> YBOL9GT 1700kg 1700kg 0kg (Shouldn't display this row)
> CL55GBP 1100kg 2200kg 1100kg
The part of jrxml:
<columnHeader>
<band height="61" splitType="Stretch">
<textField>
<reportElement x="108" y="0" width="100" height="20" uuid="205a44be-528a-4d6b-83e7-85cc0f417fd6"/>
<textFieldExpression><![CDATA[$F{car}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="219" y="0" width="100" height="20" uuid="704e546a-d4f1-4d8d-b5e7-a7ac8154d882"/>
<textFieldExpression><![CDATA[$F{expectedWeight}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="332" y="0" width="100" height="20" uuid="08846a54-7415-4f32-a0ef-41f2770e2278"/>
<textFieldExpression><![CDATA[$F{ActualWeight}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="443" y="0" width="100" height="20" uuid="7ebea114-3303-48c0-b877-f0940c62aa7f"/>
<textFieldExpression><![CDATA[$F{WeightDIFF}]]></textFieldExpression>
</textField>
</band>
</columnHeader>
Any help would be excellent
If you are using iReport designer you can select the field on screen, on the right pane of properties each field has a Print When Expression property. You can create a variable (Boolean is easiest). E.G
!$F{CarWeight1}.equals($F{CarWeight2})
Create a variable and set that as a boolean. Drop the variable into the print when expression property on each field. Also worth ticking remove line when blank for each field for formatting purposes.
Hope this helps.
As #AlexK pointed out, you can use the Print when expression.
After your <band> row, add the following (I assume $F{WeightDIFF} is an Integer):
<printWhenExpression><![CDATA[$F{WeightDIFF} > 0]]></printWhenExpression>

How to create a single pdf containing multiple invoices

I feed an xml file to JasperReports in order to generate a single invoice. This works fine.
However, I would also like to generate multiple invoices (i.e. all invoices for a given user) from a single xml file. The output should be just a single pdf file.
The XML file looks like this
<orders>
<order>
...
</order>
<order>
...
</order>
<order>
...
</order>
</orders>
Is this possible with JasperReports by just editing the jrxml file? I know that I could generate a pdf for each invoice by calling JasperReports in a loop. But I'd like to avoid this since it would require modifing a lot of code.
Update
I use the Jasper-Rails plugin for RoR to generate the reports. https://github.com/fortesinformatica/jasper-rails/blob/master/lib/jasper-rails/jasper_reports_renderer.rb
An xml for a single invoice is simply <order> ... </order>
The jrxml (note: xPath has already been changed to reflect mkl's approach) http://pastebin.com/R0vnrQgU
It is possible to generate a single PDF with multiple invoices if it before was possible to generate a PDF for a single invoice.
It is not clear how many changes to the JRXML are required. Unfortunately the OP did not provide a JRXML. To illustrate a simple case:
If the order merely contains some static amount of data and the JRXML, therefore, only essentially works on one data set, there is hardly anything to change. e.g.:
Let's assume you have original XMLs similar to this sample:
<order>
<name>Mr. Smith</name>
<quantity>2</quantity>
<item>bike</item>
<price>200</price>
</order>
and an original JRXML similar to this sample:
<queryString language="xPath">
<![CDATA[/order]]>
</queryString>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="quantity" class="java.lang.String">
<fieldDescription><![CDATA[quantity]]></fieldDescription>
</field>
<field name="item" class="java.lang.String">
<fieldDescription><![CDATA[item]]></fieldDescription>
</field>
<field name="price" class="java.lang.String">
<fieldDescription><![CDATA[price]]></fieldDescription>
</field>
<variable name="aggregated" class="java.lang.Number">
<variableExpression><![CDATA[java.lang.Integer.parseInt($F{quantity}) * java.lang.Float.parseFloat($F{price})]]></variableExpression>
</variable>
<detail>
<band height="125" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="535" height="20"/>
<textElement/>
<textFieldExpression><![CDATA["Dear " + $F{name} + ","]]></textFieldExpression>
</textField>
<textField>
<reportElement x="0" y="40" width="100" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$F{quantity}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="100" y="40" width="235" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Center"/>
<textFieldExpression><![CDATA[$F{item}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="335" y="40" width="100" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$F{price}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="0" y="75" width="535" height="35"/>
<textElement/>
<textFieldExpression><![CDATA["Please pay " + $V{aggregated} + " soon."]]></textFieldExpression>
</textField>
<textField>
<reportElement x="435" y="40" width="100" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$V{aggregated}]]></textFieldExpression>
</textField>
</band>
</detail>
Now for multi-invoice XMLs like this sample:
<orders>
<order>
<name>Mr. Smith</name>
<quantity>2</quantity>
<item>bike</item>
<price>200</price>
</order>
<order>
<name>Mr. Fisher</name>
<quantity>3</quantity>
<item>box</item>
<price>10</price>
</order>
</orders>
all you have to do in the JRXML is to change the xPath expression to match all order elements and add a page break between data sets:
...
<queryString language="xPath">
<![CDATA[//order]]>
</queryString>
...
<detail>
<band height="125" splitType="Stretch">
...
<break>
<reportElement x="0" y="124" width="535" height="1"/>
</break>
</band>
</detail>
Even if the order contains more dynamic data, e.g. a variable number of items, it might be just as easy as long as the order element defines the main data set (the variable number of items might be handled by some table element working on a subdataset).
Update
After the OP provided his JRXML file, it turns out that it essentially is of the simple type indicated above. A small correction is required, though:
The OP's JRXML uses only two sections, Title and Page Footer. The latter indeed is used for page footer material but the former is not used for a title but instead for the actual invoice body, i.e. for material which shall be printed not once (as a title) but as many times as there are data sets! To make this ready for multi-invoice outputs, therefore, the title band first has to be moved to become a detail band:
...
</background>
<title>
<band height="616" splitType="Stretch">
...
</band>
</title>
<pageFooter>
...
becomes
...
</background>
<detail>
<band height="616" splitType="Stretch">
...
</band>
</detail>
<pageFooter>
...
And due to the sheer size of this band, this already suffices to make the JRXML ready for multi-order inputs: A page break occurs automatically before the next detail section with information for the next data set because not more than one of these bands fits on a page and the band splitType is "Stretch".
The output into a single pdf isn't the point.
The key is how to use page breaks for each invoice and the use of the headers/bands, I think.

IReport: Detail band does not overflow to next page

I have two text fields inside a detail band. Here follows band XML code:
<band height="40" splitType="Prevent">
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" stretchType="RelativeToBandHeight" x="0" y="20" width="100" height="20" isPrintInFirstWholeBand="true" isPrintWhenDetailOverflows="true" uuid="67cd0dfb-9a6d-4468- 8aac-3f48e539c584"/>
<textFieldExpression><![CDATA[$F{Resposta}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" stretchType="RelativeToBandHeight" isPrintRepeatedValues="false" x="0" y="0" width="100" height="20" isPrintInFirstWholeBand="true" isPrintWhenDetailOverflows="true" uuid="c7fa90d3-2b11-4127-b319-5461a80acb2d"/>
<textFieldExpression><![CDATA[$F{Nome Questão}]]></textFieldExpression>
</textField>
</band>
As you can see, the text fields position type is "float", stretch type is "Relative to band height" print in first whole band is "true" print when detail overflows is "true" and stretch with overflow is also "true".
Band's Stretch Type is set to "Prevent".
I don't get it why it does not print all the rows I should get with my query. It should continue printing in more pages until all rows were displayed.
Any ideas?
First select your band details and set Stretch Type as "Stretch".
Secondly check and set following details by selecting your field :
Position type: float
Stretch type: relative to tallest object
Stretch with overflow: true (Checked)
Print repeated values: true (Checked)
Even if this not worked then add one more configuration -
Show out of bound content: true (Checked)
Note : If your field wrapped with frame then set frame properties also as above.
If you do above setting then I think there is no need to set detail overflows as "true".