Grouping by parameter value in jasper - jasper-reports

Well, I don't know, maybe I'm missing something, but I've been trying to group data in a jasper report, but so far the grouping appears only if the group expression is a field. Is it possible to group data by parameter value instead of field value? i.e., something like
<groupExpression><[!CDATA[$P{some_param}]]></groupExpression>
instead of
<groupExpression><[!CDATA[$F{some_field}]]></groupExpression>
in the .jrxml file?

Is it possible to group data by parameter value instead of field value?
Yes, it is, just like you mentioned. You would have no syntax errors and the report would be generated.
The problem is that it may not bring what you're expecting. The group bands are usually printed every time the "groupExpression" changes. So basically this parameter needs to be associated with something that will change during the report generation (for example, filling a parameter of a subreport with a field in way that this subreport uses this paramater as a group expression). And of course, it needs to be associated with something that makes sense and bring you the desirable behavior.
You can have something like this in your subreport:
...
<parameter name="START" class="java.util.Date"/>
<parameter name="END" class="java.util.Date"/>
...
And something like this in a detail band of your "super" report:
<subreport>
<reportElement x="0" y="10" width="555" height="200" uuid="ac2c99da-f595-4498-a518-2bfb1f31b73c"/>
<subreportParameter name="START">
<subreportParameterExpression><![CDATA[$F{start}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="END">
<subreportParameterExpression><![CDATA[$F{end}]]></subreportParameterExpression>
</subreportParameter>
...
</subreport>
Just notice I'm assuming the fields $F{end} and $F{start} are also "java.util.Date" objects.

Related

Subreport with return value gives exception "System is not facet valid with enumeration"

I'm getting an exception during compile in Jaspersoft Studio 6.4.0.
How do I address this?
I've created a report containing a subreport from which I want to return a value. To do that, I have:
Created a variable in the subreport called, "logTotal", set to the
value of another variable, which is a summation calculated in the
report. No reset type, no calculation function.
Created a variable in the main report with the same name and type.
No reset type, no calculation function.
In the main report, created a subreport return value link
between the two variables with calculation type, "System."
On compile, I'm seeing the following exception:
net.sf.jasperreports.engine.JRException: org.xml.sax.SAXParseException; lineNumber: 454; columnNumber: 91; cvc-enumeration-valid:
Value 'System' is not facet-valid with respect to enumeration '[Nothing, Count, DistinctCount, Sum, Average, Lowest, Highest, StandardDeviation, Variance, First]'. It must be a value from the enumeration.
I can choose the "System" choice from a
If I use other choices ("No calculation function," "First," "Average," etc.),
the subreport returns null.
Main Report:
<variable name="logTotal" class="java.math.BigDecimal" resetType="None"/>
...
<subreport>
<reportElement positionType="Float" x="0" y="60" width="572" height="40" uuid="d3ec84fb-528f-41f5-8b54-26112fd95b50"/>
<subreportParameter name="loadList">
<subreportParameterExpression><![CDATA[$P{loadList}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<returnValue subreportVariable="logTotal" toVariable="logTotal" calculation="System"/>
<subreportExpression><![CDATA["scaling/reports/ScaleSummary_Logs.jasper"]]></subreportExpression>
</subreport>
Subreport:
<variable name="price4" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{price}]]></variableExpression>
</variable>
<variable name="logTotal" class="java.math.BigDecimal" resetType="None">
<variableExpression><![CDATA[$V{price4}]]></variableExpression>
</variable>
It seems that the exception is the result of a mismatch between what JS Studio permits and what this particular compiler (not sure whether JSS uses the compiler I installed (6.4.1) or one that it installs) allows.
Obviously, the solution is to ensure that the compiler being used is compatible.

Get first letter of first and last row in Jasper Reports table

I am using JasperSoft Studio in Eclipse to generate a signup sheet for a church. The page header has the label of what last names will be on the page. So page 1 will have A-D, if the page starts with an A, and ends with a D.
This is turning out to be very complicated for such an easy task. I just want to read what the last_name field is in the first and last row of every page, take the first letter of it, and then stick it in the header.
Any ideas are welcome, I am stumped.
To get the first and last value of a field in a page you use variables with resetType and set the correct evalutationTime on the textField (You will need to use 2 textField aligning them correctly one next to the other)
This example will show how to get the first and last value of the field $F{Last_Name} on every page
First value of a field in the page
The resetType on your variable will be resetType="None"
<variable name="firstValueOnPage" class="java.lang.String" resetType="None">
<variableExpression><![CDATA[$F{Last_Name}]]></variableExpression>
</variable>
and in the textField, use the variable with evalution="Now" (that is default so no tag needed)
<textField>
<reportElement x="30" y="19" width="100" height="20" uuid="e6421031-6db7-4fd9-995f-94cef2eb3621"/>
<textFieldExpression><![CDATA[$V{firstValueOnPage}]]></textFieldExpression>
</textField>
Last value of a field in the page
The resetType of your variable is resetType="Page"
<variable name="lastValueOnPage" class="java.lang.String" resetType="Page">
<variableExpression><![CDATA[$F{Last_Name}]]></variableExpression>
</variable>
and in the textField use the variable evaluationTime="Page"
<textField evaluationTime="Page">
<reportElement x="170" y="19" width="100" height="20" uuid="9100baa5-0095-4dc3-ac79-2cd87562a92d"/>
<textFieldExpression><![CDATA[$V{lastValueOnPage}]]></textFieldExpression>
</textField>
To get only the first char of first and last value I see that you have already figured it out, but to complete the answer the textFieldExpression would be
<textFieldExpression><![CDATA[($V{firstValueOnPage}!=null&&$V{firstValueOnPage}.length()>0)?String.valueOf($V{firstValueOnPage}.charAt(0)).toUpperCase():""]]></textFieldExpression>
Now just put the two textField's next to each other (align them correctly) and you will have the desired result.
Some additional information to learn more about resetType and evalutationTime (from jasper report api 6.2.0)
resetType
None - The variable is incremented with every record during the iteration through the data source
Report - The variable never gets incremented during the report filling process.
Page - The variable is incremented with each new page.
Column - The variable is incremented with each new column.
Group - The variable is incremented every time the group specified by the incrementGroup attributes breaks
EvalutationTime
Auto Evaluation time indicating that each variable participating in
the expression should be evaluated at a time decided by the engine.
Band The element will be evaluated at band end.
Column A constant specifying that an expression should be evaluated after each column is filled.
Group A constant specifying that an expression should be evaluated after each group break.
Master Used for elements that are evaluated at the moment the master report ends.
Now A constant specifying that an expression should be evaluated at the exact moment in the filling process when it is encountered.
Page A constant specifying that an expression should be evaluated after each page is filled.
Report A constant specifying that an expression should be evaluated at the end of the filling process.
Report is ordered by Last_Name therefore we can use calculation Lowest and Highest
define variables:
<variable name="lowestFirstLetter" class="java.lang.String" resetType="Page" calculation="Lowest">
<variableExpression><![CDATA[$F{Last_Name}.substring(0,1)]]></variableExpression>
</variable>
<variable name="highestFirstLetter" class="java.lang.String" resetType="Page" calculation="Highest">
<variableExpression><![CDATA[$F{Last_Name}.substring(0,1)]]></variableExpression>
</variable>
and put textFields with evaluationTime="Page" into PageHeader band
<pageHeader>
<band height="35" splitType="Stretch">
<textField evaluationTime="Page">
<reportElement x="80" y="15" width="100" height="20" uuid="72af3431-eb3d-4f40-993b-4f0733e779cd"/>
<textFieldExpression><![CDATA[$V{lowestFirstLetter}]]></textFieldExpression>
</textField>
<textField evaluationTime="Page">
<reportElement x="260" y="15" width="150" height="20" uuid="0452517b-5066-4f8a-af6b-f941f1d3c1cb"/>
<textFieldExpression><![CDATA[$V{highestFirstLetter}]]></textFieldExpression>
</textField>
</band>
</pageHeader>
Good luck

jasper decimal separator being ignored

In a jasper report I use a JSON datasource.
This datasource contains numbers (e.g. 159.994).
There is a field of class java.lang.double (let's call it "doubleField") and a text field with this field and a pattern ("#,##0.00 ¤ (brutto)").
The pattern works fine (german currency format) but if I print out just the value of the doubleField the expected output would be "195,99" or "159.994".
But in fact it is "159.994,00" or "159994.0".
There was a solution changing the language of the report from "groovy" to "JavaScript" but this won't help and is also not applicable.
There is a "quick&dirty" solution (without being quick) to just take the JSON value as a String and then cast it to a double in the text field. This works fine but it's dirty and not really quick.
Any ideas?
I have a Jasper report definition. I'm just including a few things from that report definition that I think might be relevant to your problem.
First, I have several field definitions. Here are two of them:
<field name="FundFixedBeginningBalance" class="java.lang.Double">
<fieldDescription>
<![CDATA[FundFixedBeginningBalance/FundFixedBeginningBalanceValue]]>
</fieldDescription>
</field>
<field name="FundNonFixedBeginningBalance" class="java.lang.Double">
<fieldDescription>
<![CDATA[FundNonFixedBeginningBalance/FundNonFixedBeginningBalanceValue]]>
</fieldDescription>
</field>
Note how both are defined with class="java.lang.Double". I'm using XPath expressions because my data is in XML, but that is not fundamentally different from JSON. Later, in the report layout section I have:
<textField pattern="#,##0.00 ;(#,##0.00)" isBlankWhenNull="true">
<reportElement positionType="Float" x="368" y="52" width="100" height="14" uuid="deac984d-39b8-49f4-b4d2-28e66681c098">
<property name="local_mesure_unitx" value="pixel"/>
<property name="com.jaspersoft.studio.unit.x" value="px"/>
</reportElement>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$F{FundFixedBeginningBalance} + $F{FundNonFixedBeginningBalance}]]></textFieldExpression>
</textField>
Notice there is no casting within the textFieldExpression element; just substituting both fields in with $F and adding them together (and this prints correctly). Are you doing something different?

How to pass date as a field in jrxml of JasperReports?

I want to pass date as a field to the jrxml.
Following is the code for it.
<xyLineChart>
<chart evaluationTime="Band">
<reportElement x="0" y="0" width="555" height="500"/>
</chart>
<xyDataset>
<dataset incrementType="None"/>
<xySeries>
<seriesExpression><![CDATA["CpuUsageGraph"]]></seriesExpression>
<xValueExpression><![CDATA[new java.util.Date($F{time}.getTime())]]></xValueExpression>
<yValueExpression><![CDATA[$F{cpuUsage}]]></yValueExpression>
</xySeries>
</xyDataset>
<linePlot>
<plot/>
</linePlot>
</xyLineChart>
But it is not working.
Its giving error as can not cast from date to number.
Then how to convert it?
You are using the time field in the constructor of Date. No need for that.
Instead of this:
java.util.Date($F{time}.getTime())
use this:
$F{time}
If you want the long value of it: then use this
$F{time}.getTime()
UPDATE
I didn't notice you are using a chart, here is a new answer:
In charts, X and Y value expressions should be any Number object, check subclasses in Number Class JavaDoc, in your case you are getting the long value of your Time field, which cannot be cast to Number, you will need to define a new object, for example:
new Long($F{time}.getTime())
Side Note: in this case the report will compile and work, BUT, you are getting the number of milliseconds and using it in your chart. I don't think that is what you want exactly. So i would suggest extracting a specific field from your Date field like Day. Month, Year ... etc
I cannot see the attached JRXML. However, open your JRXML file in a text editor, and check that the field is defined something like this:
<field name="MyDate" class="java.util.Date"/>

How do I print a list of strings contained within another list in iReport?

I am creating a simple reporting program using java and iReport (from jasper), which is supposed to create a report in pdf showing PCs with their IP address, their location, whether it's idle or not at the moment (handled by another system), and a list of projects it is currently attached to (managed elsewhere, too).
I'm using iReport for this matter, and have created a dummy collection generating class as follows:
public class PCReports {
public static java.util.Collection PC_collection;
public static java.util.Collection generateCollection() {
PC_collection = new ArrayList<PCLineDTO>();
PCLineDTO line = new PCLineDTO();
line.setIP("192.168.1.1");
line.setLab("location");
line.setActive(true);
line.addProjectName("project1");
line.addProjectName("project2");
line.addProjectName("project3");
PC_collection.add(line);
line = new PCLineDTO();
line.setIp("192.168.1.2");
line.setLab("location2");
line.setActive(false);
line.addProjectName("project1");
line.addProjectName("project2");
PC_collection.add(line);
return PC_collection;
}
}
The entity class in this case being:
public class PCLineDTO {
private String ip;
private String lab;
private Boolean active;
private ArrayList<String> projects;
}
After some searching around the Internet, I found a way to do something similar, using subreports.
The thing is, I don't know how to print a collection of strings passed as a dataSource to this subreport.
In the examples I found on the Internet, for each item in the master collection, the subreports were passed a collection of objects -with their own getter methods for each attribute- instead of a collection of strings as is the case here. In those cases, they accessed the values they needed to use via the iReport syntax, which I was not able to use, for example:
$F{project}
Since iReport looks for a getProject method contained within the objects it receives, but in this case it's a simple String object (without a getProject method, as it were).
Use a subreport or a subdataset.
Pass the subreport a collection datasource
JRBeanCollectionDataSource($F{Projects})
Then in the new subreport create a new field called "_THIS" exactly, this means the bean in the collection passed is the same as the value i want
For more info, check the source code of the class here: JRAbstractBeanDataSource
Note: this is available in JasperReport 3.0.0 im not sure if it exists in previous builds.
Hope this helps
Update: just checked the SVN, seems like this feature is implemented in JasperReports 2.0.0
Interesting. I think you'd better use the List, and then define getName() on the Project class. Then in the subreport define a variable "name". It will work this way, and it will allow you to add easily additional information, like project duration, team-lead, etc.
As Bozho says, in case proyects was an array of complex object you should reference it as a field of type java.util.Collection an then pass it to the inner subreport the same way medopal indicates. And don´t put the _THIS field.
To elaborate on this without using _THIS: let's say a java bean has a list of subBeans and this subBean has a complex format and we want to print each subBean in a custom way. I quote an example where the subDataset element is on the report level and the componentElement is in the detail band:
<subDataset name="ListOfSubBeans" uuid="66c86e41-c565-4f18-bccf-1a1b2a567585">
<field name="subBeanField_1" class="java.lang.String">
<fieldDescription><![CDATA[subBeanField_1]]></fieldDescription>
</field>
</subDataset>
...
<componentElement>
<reportElement x="780" y="0" width="100" height="30" uuid="f73864b9-46dd-4adb-8dad-a6bd8dfae64e">
<property name="net.sf.jasperreports.export.headertoolbar.table.name" value=""/>
</reportElement>
<jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
<datasetRun subDataset="ListOfSubBeans" uuid="a8dd1c2b-3ac0-4ffa-b9d0-08e4890e199a">
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{listOfSubBeans})]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="100">
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="61700c18-6bb9-45da-a235-b76b9f76a2ea"/>
<textFieldExpression><![CDATA[$F{subBeanField_1}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
...
So, the master dataset has declared that the master bean has a member variable that is a list: listOfSubBeans. This java.util.List is used to feed the datasource of the jr:list, while the fields of the jr:list are declared using a subDataset called ListOfSubBeans (pay attention to case sensitivity).