PieChart: When and how we should use Increment Type? - jasper-reports

The code of my servlet:
JasperCompileManager.compileReportToFile(jrxmlSourcePathMain,
jrxmlDestPathMain);
InputStream isRef = new FileInputStream(new File(jrxmlDestPathMain));
ServletOutputStream sosRef = response.getOutputStream();
response.setContentType("application/pdf");
JasperRunManager.runReportToPdfStream(isRef, sosRef, new HashMap(),
new JRBeanCollectionDataSource(buyBookInfoList));
sosRef.flush();
sosRef.close();
The snippet of jrxml file:
<summary>
<band height="265" splitType="Stretch">
<pieChart>
<chart isShowLegend="true" renderType="svg" theme="default">
<reportElement uuid="c6a09cc9-bd15-4b09-8657-05868a148f18" x="0" y="0" width="554" height="265"/>
<chartTitle position="Top" color="#FF0000">
<font fontName="宋体" size="18" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
<titleExpression><![CDATA["报表演示"]]></titleExpression>
</chartTitle>
<chartSubtitle color="#0000FF">
<font fontName="宋体" size="14" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
<subtitleExpression><![CDATA["子标题"]]></subtitleExpression>
</chartSubtitle>
<chartLegend textColor="#33FF33" backgroundColor="#6666FF" position="Right">
<font size="12" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</chartLegend>
</chart>
<pieDataset>
<keyExpression><![CDATA[$F{username}]]></keyExpression>
<valueExpression><![CDATA[$F{buyBookNum}]]></valueExpression>
</pieDataset>
<piePlot isShowLabels="true" isCircular="false" labelFormat="姓名为:{0}">
<plot orientation="Horizontal" labelRotation="180.0"/>
<itemLabel/>
</piePlot>
</pieChart>
</band>
</summary>
I set Increment Type property for PieChart value with different values: none, report, page. But I did not notice any difference in generated reports.
So my question is how to use the PieChart's Increment Type property?
What is a purpose of this property?

The increment type allows you to tell the pie chart when to select values to use. For example, if you want to create a pie chart that shows sales in the USA, Canada, and Mexico, you might increment over a "country" group.

Related

Jasper Report Crosstab with ArrayList of Data

I am trying to create Jasper Report with crosstab by writing JRXML with DTOs.
I am trying to create rows dynamic number of chargeCodes and their total. It looks something like this:
jobNo
chargeCodeA
chargeCodeB
Total
jobNoABC
100.10
300.30
400.40
jobNoDEF
200.20
400.40
600.60
In my Java backend, I have DTO which looks like this
class MyDTO {
private String jobNo;
private List <String> chargeCode = new ArrayList <> ();
private List <BigDecimal> chargeCodeTotal = new ArrayList <> ();
}
where the list codeCode contains chargeCodeA, chargeCodeB for jobNoABC
and chargeCodeTotal contains 100.10, 300.30 for jobNoABC also.
In my JRXML, I have this:
<?xml version="1.0" encoding="UTF-8" ?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
name="vendorBillingCompletedJobReport" leftMargin="5" rightMargin="5">
<parameter name="lblJobNo" class="java.lang.String" isForPrompting="false"/>
<field name="jobNo" class="java.lang.String"/>
<field name="chargeCode" class="java.util.List"/>
<field name="chargeCodeTotal" class="java.util.List"/>
<summary>
<band height="60">
<crosstab>
<reportElement width="782" y="0" x="0" height="60" />
<rowGroup name="jobNo" width="100" totalPosition="End">
<bucket>
<bucketExpression class="java.util.List">
<![CDATA[$F{jobNo}]]>
</bucketExpression>
</bucket>
<crosstabRowHeader>
<cellContents>
<box>
<pen lineColor="black" lineWidth="1"/>
</box>
<textField>
<reportElement width="100" y="0" x="0" height="20" />
<textElement textAlignment="Right" verticalAlignment="Middle" />
<textFieldExpression>
<![CDATA[$V{jobNo}]]>
</textFieldExpression>
</textField>
</cellContents>
</crosstabRowHeader>
<crosstabTotalRowHeader>
<cellContents>
<box>
<pen lineColor="black" lineWidth="1"/>
</box>
<staticText>
<reportElement x="0" y="0" width="60" height="20" />
<textElement verticalAlignment="Middle" />
<text>TOTAL</text>
</staticText>
</cellContents>
</crosstabTotalRowHeader>
</rowGroup>
<columnGroup name="chargeCode" height="20" totalPosition="End">
<bucket>
<bucketExpression class="java.util.List">
$F{chargeCode}
</bucketExpression>
</bucket>
<crosstabColumnHeader>
<cellContents>
<box>
<pen lineColor="black" lineWidth="1"/>
</box>
<textField isStretchWithOverflow="true">
<reportElement width="60" y="0" x="0" height="20" />
<textElement verticalAlignment="Bottom" />
<textFieldExpression>
<![CDATA[$V{chargeCode}]]>
</textFieldExpression>
</textField>
</cellContents>
</crosstabColumnHeader>
<crosstabTotalColumnHeader>
<cellContents>
<box>
<pen lineColor="black" lineWidth="1"/>
</box>
<staticText>
<reportElement width="60" y="0" x="0" height="20" />
<textElement verticalAlignment="Bottom" />
<text>TOTAL</text>
</staticText>
</cellContents>
</crosstabTotalColumnHeader>
</columnGroup>
<measure name="chargeCodeTotalCount" class="java.math.BigDecimal" calculation="Sum">
<measureExpression>$F{chargeCodeTotal}</measureExpression>
</measure>
<crosstabCell height="20" width="60">
<cellContents backcolor="#FFFFFF">
<box>
<pen lineColor="black" lineWidth="1"/>
</box>
<textField>
<reportElement x="5" y="0" width="55" height="20" />
<textElement textAlignment="Left" verticalAlignment="Bottom" />
<textFieldExpression class="java.math.BigDecimal">
$V{chargeCodeTotalCount}
</textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
</crosstab>
</band>
</summary>
</jasperReport>
But I am getting error:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.Comparable
at org.apache.commons.collections.comparators.ComparableComparator.compare(ComparableComparator.java:91)
I am not sure how to create infinite number of chargeCodes using JRXML.
And I cannot use Dynamic Jasper. I can only think of crosstab. Please help. Thanks.

<printWhenExpression> is not working for conditional display of array of json objects in jasper

I'm beginner to jasper and working on a report where I need to display the header of a table only when data is present in it. I have currently below code snippet in my jrxml:
<frame>
<reportElement stretchType="ContainerHeight" x="240" y="37" width="110" height="52" uuid="some-uuid">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</reportElement>
<staticText>
<reportElement positionType="Float" x="0" y="0" width="110" height="16" uuid="some-uuid">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</reportElement>
<textElement>
<font size="12" isBold="true"/>
</textElement>
<text><![CDATA[EMPLOYEES]]></text>
</staticText>
<componentElement>
<reportElement positionType="Float" x="0" y="16" width="110" height="16" isRemoveLineWhenBlank="true" uuid="some-uuid">
<property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
</reportElement>
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<datasetRun subDataset="employeesDataSet" uuid="some-uuid">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("employees")]]></dataSourceExpression>
</datasetRun>
<jr:column width="110" uuid="some-uuid">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/>
<jr:detailCell height="16">
<textField isStretchWithOverflow="true">
<reportElement style="paragraph" stretchType="ElementGroupHeight" x="0" y="0" width="110" height="16" isRemoveLineWhenBlank="true" uuid="some-uuid"/>
<textElement markup="html">
<font size="12"/>
</textElement>
<textFieldExpression><![CDATA["<B>" +($F{type} != null ? $F{type} : "") + "</b> " + ($F{result} != null ? $F{result} : "") + ", " + ($F{value} != null ? $F{value} : "") + " " + ($F{unit} != null ? $F{unit} : "")]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
</componentElement>
</frame>
JSON from which data is being written to report looks like:
"employees": [
{
"type": "HR",
"result": "1",
"value": "Positive"
},
{
"type": "MD",
"result": "3",
"value": "Positive"
}
]
How can I display the static header EMPLOYEES only when data is present and not display anything when there is no data in JSON?
I have tried adding in <static text> but it didn't work :
<printWhenExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("employees") != null]]></printWhenExpression>
I have found the solution and posting it here so that other people facing similar issue can refer.
To check if json array has more elements, use next() method. This line worked for me :
<printWhenExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("employees").next()]]></printWhenExpression>

List component displays only the first row

In my JasperReport's report only the first row of my collection gets displayed. Here is the relevant code.
The entity
public class LegendEntity implements Serializable{
private String label;
private Image bufferedImage;
public LegendEntity() {
}
public LegendEntity(String label) {
this.label = label;
}
public LegendEntity(String label,Image bufferedImage) {
this.label = label;
this.bufferedImage = bufferedImage;
}
//getters-setters
Preparing the datasource:
List<MyEntity> myEntitiesList = new ArrayList<>();
//filling the list
JRBeanCollectionDataSource entityDS= new JRBeanCollectionDataSource(myEntitiesList ,false);
report.getReportParameters().put("ENTITY_DATASOURCE", entityDS);
The jrxml:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport ... name="SampleReport" printOrder="Horizontal" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="595" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
<subDataset name="LegendDataset" uuid="e0d72aca-6fd5-4935-b57f-ff5a436f2afb">
<field name="label" class="java.lang.String">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<field name="bufferedImage" class="java.awt.Image"/>
</subDataset>
<parameter name="P_MAP_SCALE_STR" class="java.lang.String"/>
<parameter name="ENTITY_DATASOURCE" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<detail>
<band height="842" splitType="Stretch">
<property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.FreeLayout"/>
<frame>
<reportElement x="298" y="635" width="298" height="206" uuid="e807b35a-857c-43ba-a080-13f422eb1456"/>
<componentElement>
<reportElement x="11" y="11" width="275" height="186" uuid="d6f579d3-75de-4745-8f94-c974d2e697a0"/>
<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="LegendDataset" uuid="ee194811-e7e5-4102-83ff-b150901d73c9">
<dataSourceExpression><![CDATA[$P{ENTITY_DATASOURCE}]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="186" width="275">
<staticText>
<reportElement x="10" y="10" width="130" height="20" uuid="4260f10d-ee62-4cf6-8023-d0dc2266f4dd"/>
<textElement textAlignment="Center"/>
<text><![CDATA[ENTITY LABEL]]></text>
</staticText>
<staticText>
<reportElement x="150" y="10" width="100" height="20" uuid="88135c50-3c17-4b0f-b7e5-b05987f98b02"/>
<textElement textAlignment="Center"/>
<text><![CDATA[ENTITY SYMBOL]]></text>
</staticText>
<textField isStretchWithOverflow="true" isBlankWhenNull="true">
<reportElement x="10" y="31" width="130" height="18" uuid="30885d06-38db-4b1c-a312-616a60ee1c42"/>
<textFieldExpression><![CDATA[$F{label}]]></textFieldExpression>
</textField>
<image>
<reportElement x="150" y="31" width="100" height="18" uuid="0020adca-acad-4915-9f0d-88d75e4897c7"/>
<imageExpression><![CDATA[$F{bufferedImage}]]></imageExpression>
</image>
</jr:listContents>
</jr:list>
</componentElement>
</frame>
<staticText>
<reportElement x="30" y="600" width="80" height="18" uuid="6c1afd65-a8d4-4e3f-9a56-d09abe7ec904"/>
<textElement textAlignment="Right">
<font fontName="DejaVu Sans" size="9" isBold="true"/>
</textElement>
<text><![CDATA[Ölçek: 1/]]></text>
</staticText>
<textField>
<reportElement positionType="Float" x="110" y="600" width="100" height="18" uuid="6360a545-63af-48cc-987d-d828c24a3b2a"/>
<textElement>
<font fontName="DejaVu Sans" size="9" isBold="true"/>
</textElement>
<textFieldExpression><![CDATA[$P{P_MAP_SCALE_STR}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
And on the report only the first entity's label and symbol is displayed. What am I missing?
Debugging already done and I am sure that 1+ entities are present in the list.
The whole JRXML here .
You can try to put variables in white zone in table. Not in blue/header zone.
It works for me.
I have noticed at least 2 problems in your main JRXML:
Setting printOrder="Horizontal" at the report level may prevent proper elements overflow. Try reverting to printOrder="Vertical" or remove the attribute completely.
There is too much whitespace inside the list element that would force overflow. You should not have white space after the last elements.

jasper report textfield height is not dynamic [duplicate]

I am using jasper report as reporting tool in my application. And I am wondering how can i wrap the long text by expanding the reportElement dynamically into vertical direction ( expanding the row size, not column width). Or Is there any way to achieve this? My approach below is truncating the long text "Some very long name". Can you please give me some suggestions?
Output :
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.sf.jasperreports.view.JasperViewer;
public class JrUtils {
public static void showJrReport(List objectList, String fileName, String title, Map parameters) {
try {
File f = new File(fileName);
JasperDesign jasperDesign = JRXmlLoader.load(f.getAbsolutePath());
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(objectList);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, ds);
JasperViewer jv = new JasperViewer(jasperPrint, false);
jv.setTitle(title);
jv.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
List<Person> pList = new ArrayList<Person>();
Person p1 = new Person();
p1.setPersonName("Some Name ");
p1.setAddress("Nepal - Address Fits Here");
Person p2 = new Person();
p2.setPersonName("Some very long name");
p2.setAddress("Nepal - Address Fits Here");
pList.add(p1);
pList.add(p2);
showJrReport(pList, "testReport.jrxml", "Test Report", new HashMap<Object, Object>());
}
}
Jasper Report JrXML file - testReport.jrxml :
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report name" pageWidth="250" pageHeight="400" columnWidth="210" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="2.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<field name="personName" class="java.lang.String"/>
<field name="address" class="java.lang.String"/>
<columnHeader>
<band height="23" splitType="Stretch">
<rectangle>
<reportElement x="0" y="0" width="88" height="23"/>
</rectangle>
<rectangle>
<reportElement x="88" y="0" width="122" height="23"/>
</rectangle>
<staticText>
<reportElement x="0" y="0" width="88" height="23"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Name]]></text>
</staticText>
<staticText>
<reportElement x="88" y="0" width="122" height="23"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Address]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="21" splitType="Stretch">
<rectangle>
<reportElement x="0" y="0" width="88" height="21"/>
</rectangle>
<textField>
<reportElement x="0" y="0" width="88" height="21"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{personName}]]></textFieldExpression>
</textField>
<rectangle>
<reportElement x="88" y="0" width="122" height="21"/>
</rectangle>
<textField>
<reportElement x="88" y="0" width="122" height="21"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{address}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
I found the answer myself :
I did some extra research about the properties of textField and rectangle components. And found that I need to set the following properties.
For rectangle :
<rectangle>
<reportElement stretchType="RelativeToBandHeight" ... />
</rectangle>
For textField :
<textField isStretchWithOverflow="true">
...
</textField>
Output as expected :
The <detail> ...</detail> section after correction :
<detail>
<band height="21" splitType="Stretch">
<rectangle>
<reportElement stretchType="RelativeToBandHeight" x="0" y="0" width="88" height="21"/>
</rectangle>
<textField isStretchWithOverflow="true">
<reportElement x="2" y="0" width="84" height="21"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{personName}]]></textFieldExpression>
</textField>
<rectangle>
<reportElement stretchType="RelativeToBandHeight" x="88" y="0" width="122" height="21"/>
</rectangle>
<textField isStretchWithOverflow="true">
<reportElement x="90" y="0" width="118" height="21"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{address}]]></textFieldExpression>
</textField>
</band>
</detail>
UPDATE
You can also set property net.sf.jasperreports.print.keep.full.text to true to achieve that across your all reports.
Also you can make the truncation elegant by using the following properties set to the textfield. Check this sample
net.sf.jasperreports.text.truncate.at.char
net.sf.jasperreports.text.truncate.suffix
net.sf.jasperreports.print.keep.full.text
Go to the Text Field Properties then set Text Adjust to StretchHeight.

Displaying object as image inside a list component

Problem
I have to display an object as an image inside a list component based on a particular count (intNote). While using an image path from specific location the images are displayed.
Question
How can I display an object as an image inside a list component?
Source
The JRXML:
<subDataset name="Q2">
<field name="strVert" class="java.awt.Image"/>
</subDataset>
<field name="intNote" class="java.lang.Integer"/>
<componentElement>
<reportElement x="130" y="72" width="25" height="35"/>
<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="Horizontal" ignoreWidth="true">
<datasetRun subDataset="Q2">
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JREmptyDataSource($F{intNote})]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="35" width="25">
<image isUsingCache="false">
<reportElement x="3" y="10" width="16" height="17" forecolor="#FFFFFF"/>
<graphicElement>
<pen lineWidth="1.25"/>
</graphicElement>
<imageExpression class="java.awt.Image"><![CDATA[$F{strVert}]]></imageExpression>
</image>
</jr:listContents>
</jr:list>
</componentElement>
Thank you.
In jasper you can display images by putting the current image location instead of the varible intNote.it is the only possible way to get the image in the output.
Try to make $F{strVert} class as java.io.InputStream