JasperReport: sum fields disappear after xls sorting - excel

I have such xls file generated by jasper:
sum fields has following jrxml properties:
<textField isStretchWithOverflow="true" isBlankWhenNull="true">
<reportElement positionType="Float" stretchType="RelativeToTallestObject" x="1050" y="13" width="90" height="11" isPrintWhenDetailOverflows="true" uuid="a41d8696-c8a2-43bc-a41c-1bfe5499d3d4"/>
<textElement textAlignment="Right">
<font size="8" isBold="true"/>
<paragraph lineSpacing="1_1_2"/>
</textElement>
<textFieldExpression>##my_experssion##</textFieldExpression>
</textField>
After I sort by column I sum fields disappear
Is there any simple way to fix this?

Related

How to turn a <circle> (that's inside an svg) into a checkbox?

PART 1 -
So I have a bunch of <circle>'s inside a SVG, and I want those circles to be checkboxes. And after that I want to:
PART 2 -
When circle 1 (which is now a checkbox) is clicked, then it is checked. But all the other circles now get unchecked.
This is what I've already tried:
PART 1 - Turning the SVG into a checkbox:
<circle opacity="0.5" cx="842" cy="451.814" r="25.582" class="svg_spot" id="1" fill="#FFB60C" >
<animate attributeName="r" values="25.582; 33; 25.582" keyTimes="0; 0.5; 1" begin="0s" dur="1s" repeatCount="indefinite" calcMode="linear" />
<input type="checkbox" id="spot1" name="spot" class="common_selector spot_id" value="spot1">
</circle>
PART 2 -
$('input[name=spot]').click (function (){
$(this).attr('checked', true);
$('input[name=spot]').not(this).attr('checked', false);
});
Thanks for your time guys. Would appreciate any help!
It is possible to get this working without any Javascript.
How this works:
Put the SVG in the label of the input. Clicking on the SVG (ie the label) will thus activate the field.
Make the actual <input> field invisible, so that all you see is the label.
Style the SVG based on whether the field is selected, by using the :checked pseudo-selector.
// just here to prove that the form value is changing
// prints value of spot field when inputs change
document.querySelectorAll("#spot1, #spot2, #spot3")
.forEach((elem) => elem.addEventListener("change", (evt) => console.log(document.myform.spot.value)));
.common_selector {
position: absolute;
opacity: 0;
}
.common_selector + label svg {
width: 50px;
height: 50px;
fill: red;
}
.common_selector:checked + label svg {
fill: green;
}
<form name="myform">
<input type="radio" id="spot1" name="spot" class="common_selector spot_id" value="spot1">
<label for="spot1">
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50"/>
</svg>
</label>
<input type="radio" id="spot2" name="spot" class="common_selector spot_id" value="spot2">
<label for="spot2">
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50"/>
</svg>
</label>
<input type="radio" id="spot3" name="spot" class="common_selector spot_id" value="spot3">
<label for="spot3">
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50"/>
</svg>
</label>
</form>
<input> is not a valid SVG element - it is a HTML element, so this won't work. You can either:
wrap an input element inside a <foreignObject> element and do it that way, or
you could use positioning to place the input element over the circle. But fair warning - form elements haven't always played well when they're positioned over other types of elements. Or
You can manually draw SVG that looks like an input element and use JavaScript to make it behave like one. or
Since you just need a circle, why not wrap the input element in a Div with an appropriate border radius and make a circle that way.
PART 1:
Use <foreignObect> to display any HTML element inside an SVG:
<foreignObject x="20" y="20" width="100" height="100">
<input type="checkbox" id="spot1" name="spot" class="common_selector spot_id"
value="spot1">
</foreignObject>
Then you can use css to hide default styling of this input field and position your circle over it. You can read about it here: https://www.w3schools.com/howto/howto_css_custom_checkbox.asp
PART 2:
Use Radio Buttons instead of Checkboxes. Checkboxes allow more than one selection. Radio buttons are what you need here. Read about it here: https://www.w3schools.com/tags/att_input_type_radio.asp
I hope I understand your question. You can not change an svg element into an input however you can try to mimic one.
// selects all the circles with a class of radio
let inputs = document.querySelectorAll(".radio")
// for every circle
inputs.forEach(i =>{
//when the circle is clicked
i.addEventListener("click", ()=>{
// remove the class checked from all the circles but the clicked one
inputs.forEach(j =>{if(i!==j)j.classList.remove("checked") })
// toggle the class checked on the clicked one
i.classList.toggle("checked")
})
})
svg{border:1px solid}
.checked{fill:red}
<svg id="theSVG" viewBox="800 410 300 85" width="300">
<circle class="radio" opacity="0.5" cx="842" cy="451.814" r="25.582" fill="#FFB60C" stroke="#FFB60C" stroke-width="10" />
<circle class="radio" opacity="0.5" cx="950" cy="451.814" r="25.582" fill="#FFB60C" stroke="#FFB60C" stroke-width="10" />
<circle class="radio" opacity="0.5" cx="1050" cy="451.814" r="25.582" fill="#FFB60C" stroke="#FFB60C" stroke-width="10" />
</svg>
It sounds like you want to use an SVG as a type of "selector" like a color selector or, in my case a planet selector. Here I have a SVG representing the solar system where the user clicks on a planet to select it. Since it sounds like you only want to select a single item then a radio button is the better option, however the method below should work with either.
As others have suggested the foreignObject element can be used. I had issues getting it work without specifically declaring a prefixed namespaces for the svg and saving the file with a .xhtml extension.
Of course there are plenty of ways to do something similar with javaScript, however a big advantage of using an underlying radio button is that it takes care of all the logic and makes validation easier.
I used an empty div over the circle that is acting as a label for the radio button. Since clicking on the label activates the radio button the circle now functions as a radio button!
The SVG does not show up in the snippet, so the div's are shaded for visibility. The actual radio buttons can be hidden if desired.
div{
border: red solid 1px;
background-color: black;
opacity: 20%;
}
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
<p>Select a planet</p>
<form name="planetData">
<input id="venus" name="planet" type="radio" value="venus" />
<label for="venus">Venus</label>
<input id="earth" name="planet" type="radio" value="earth" />
<label for="venus">Earth</label>
<input id="mars" name="planet" type="radio" value="mars" />
<label for="venus">Mars</label>
</form>
<svg:svg height="100" width="100" viewbox="0 0 100 100">
<svg:circle cx="0" cy="50" r="10" fill="yellow"/>
<svg:circle cx="30" cy="75" r="10" fill="green"/>
<svg:circle cx="60" cy="30" r="10" fill="blue"/>
<svg:circle cx="90" cy="60" r="10" fill="red"/>
<svg:foreignObject x="20px" y="65px" height="20px" width="20px">
<label for="venus">
<div style="height: 30px; width: 30px;">
</div>
</label>
</svg:foreignObject>
<svg:foreignObject x="50" y="20" height="20" width="20">
<label for="earth">
<div style="height:20px; width: 20px;"></div>
</label>
</svg:foreignObject>
<svg:foreignObject x="80" y="50" height="20" width="20">
<label for="mars">
<div style="height:40px; width: 40px;"></div>
</label>
</svg:foreignObject>
</svg:svg>
</html>

Pagination adds an extra blank page at the end

Given the footer of my report :
<pageFooter>
<band height="51" splitType="Stretch">
<textField isStretchWithOverflow="true">
<reportElement positionType = "Float" x="485" y="1" width="55" height="50" uuid="7786fb05-689a-4b6a-915a-a7bcf3abad95"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Calibri" size="10" />
<paragraph lineSpacingSize="0"/>
</textElement>
<textFieldExpression><![CDATA[" - "]]> + $V{PAGE_NUMBER} + <![CDATA[" - "]]></textFieldExpression>
</textField>
</band>
</pageFooter>
My report adds an extra blank page without page number at the end of the report unlike the previous report pages each of which has a page number. When I have tried to remove the pagination and use a staticText component as my footer, the extra blank page is gone.
How could one solve this problem please?

How to group properly excel data source with rowspan?

From my understanding, <groupExpression> tag will be the one that decides whether a new group will be created or not, if there's a change to the element inside <groupExpression>, a new group will be created.
I want my report to look similar to my Excel data source (refer below) hence I want to group the ID and Name in the Excel file. In my jasperReport.jrxml (refer below), my <groupExpression> for Group1 is the ID column of my Excel File. But when I preview the report (refer below), the ID and Name column is not grouped, instead, there's a null string.
How to properly group them and eliminate the null string?
Excel datasource:
jasperReport.jrxml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.2.0.final using JasperReports Library version 6.2.0 -->
<!-- 2016-01-26T15:33:41 -->
<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="FirstJasperReport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="8b8832df-588e-4202-826e-a6b3efcbd22b">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ExcelDataBase"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="ID" class="java.lang.Integer"/>
<field name="Name" class="java.lang.String"/>
<field name="Title" class="java.lang.String"/>
<field name="Balance" class="java.lang.Integer"/>
<variable name="Balance1" class="java.lang.Integer" resetType="Group" resetGroup="Group1" calculation="Count">
<variableExpression><![CDATA[$F{Balance}]]></variableExpression>
</variable>
<variable name="Balance2" class="java.lang.Integer" resetType="Group" resetGroup="Group1" calculation="Sum">
<variableExpression><![CDATA[$F{Balance}]]></variableExpression>
</variable>
<group name="Group1">
<groupExpression><![CDATA[$F{ID}]]></groupExpression>
<groupHeader>
<band height="30">
<rectangle>
<reportElement x="0" y="0" width="400" height="30" backcolor="#DEFCF2" uuid="de6c2f8d-afa6-45b4-b40e-574f2e07057e"/>
</rectangle>
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="c028645d-9b29-42d3-b91e-d47f15a5b44a"/>
<textFieldExpression><![CDATA[$F{ID}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="100" y="0" width="100" height="30" uuid="85d2844f-ef91-47a1-9223-c6943a25fe4d"/>
<textFieldExpression><![CDATA[$F{Name}]]></textFieldExpression>
</textField>
</band>
</groupHeader>
......
Preview result:
How to make title1 and title2 appear under the group test1, without the null string (similar to the Excel source file)?
The problem is that the excel datasource is passing $F{ID}==null for second record. This generates the null group (as you can see also the name is null).
The easiest way to fix it is to not use rowspan in excel (include all data in the excel sheet).
If this is not possible you need to save the first $F{ID} value and return this if $F{ID}==null
Example
<variable name="First_ID" class="java.lang.Integer" resetType="Group" resetGroup="Group1" calculation="First">
<variableExpression><![CDATA[$F{ID}]]></variableExpression>
</variable>
In group return variable $V{First_ID} if $F{ID}==null
<group name="Group1">
<groupExpression><![CDATA[$F{ID}==null?$V{First_ID}:$F{ID}]]></groupExpression>
... your groupHeader ....
</group>

how to order an svg visibility animation to toggle do one image after another

I want to make some images included in an svg file toggle on and off in order. To do this I need to know how to set my begin and dur attributes on the animate element.
Assuming I have images like the following
<image visibility="visible" xlink:href="image1.gif" x="0" y="0" height="100%" width="100%">
<animate attributeName="visibility" begin="0s"
from="visible" to="hidden" dur="5s" repeatCount="indefinite" />
</image>
<image visibility="hidden" xlink:href="image2.gif" x="0" y="0" height="100%" width="100%">
<animate attributeName="visibility" begin="5s"
from="hidden" to="visible" dur="4s" repeatCount="indefinite" />
</image>
How do I get them to toggle their visibility in order, so that the first image is visible at first for 4 seconds, it turns invisible the next image is visible for exactly 4 seconds, it turns invisible and the previous image is now visible for the next 4 seconds.
I would really prefer to do this with the declarative animation style.
Ok I figured out how to do it from an example in the book SVG Unleashed http://my.safaribooksonline.com/book/photo-and-graphic-manipulation/0672324296
<image visibility="visible" xlink:href="image1.gif" x="0" y="0" height="100%" width="100%">
<animate id="img1ani" attributeName="visibility" begin="1s; img2ani.end+1s"
from="visible" to="hidden" dur="5s" fill="freeze" />
</image>
<image id="img2" visibility="hidden" xlink:href="image2.gif" x="0" y="0" height="100%" width="100%">
<animate id="img2ani" attributeName="visibility" begin="img1ani.end+1s"
from="hidden" to="visible" dur="5s"/>
</image>
just in case anyone else has the same problem,img1ani begins after 1 second or 1 second after image2ani ends while img2ani begins 1 second after img1ani ends.
So in this way it toggles between the two images.

Excel not well formated in JasperReports

When i export my report to Excel, my cells don't display the whole text if there is more than one row to be displayed in it; it just cuts a part of it and i need to expand the row manually to see the all the data in it
I use the following formatting:
<band height="21">
<staticText>
<reportElement style="pageHeader" mode="Opaque" x="0" y="6" width="88" height="15"/>
<textElement textAlignment="Left">
<font fontName="Cambria" size="10"/>
</textElement>
<text><![CDATA[First Name]]></text>
</staticText>
</band>
<band height="30" splitType="Prevent">
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" stretchType="RelativeToTallestObject" x="0" y="0" width="88" height="25"/>
<textElement textAlignment="Left">
<font fontName="Cambria" size="10"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{firstName}]]></textFieldExpression>
</textField>
</band>
Is there a xls property i should set?
I solved this problem setting line spacing to double at text field properties menu.
Dosn't look different but shows full text.

Resources