How to print/display MathML expressions? - java

Currently I'm trying to use a textField with markup="html" but it's not working.
Example
<textField isStretchWithOverflow="true" isBlankWhenNull="true">
<reportElement positionType="Float" stretchType="RelativeToTallestObject" x="100" y="0" width="450" height="25" isPrintWhenDetailOverflows="true" uuid="1aeaa5e9-4136-4239-a301-2733598340d9">
<property name="com.jaspersoft.studio.unit.height" value="pixel"/>
<property name="com.jaspersoft.studio.unit.width" value="pixel"/>
</reportElement>
<textElement verticalAlignment="Middle" markup="html">
<paragraph lineSpacing="Single" leftIndent="5" rightIndent="3"/>
</textElement>
<textFieldExpression><![CDATA[$F{question}]]></textFieldExpression>
$F{question} contain:
"<p id="id"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>A</mi><mo>+</mo><mo> </mo><mi>B</mi><mo> </mo><mo> </mo><msqrt><mi>c</mi><mfenced><mrow><mi>d</mi><mfenced open="[" close="]"><mi>r</mi></mfenced></mrow></mfenced></msqrt><mo> </mo><mi>δ</mi><mo> </mo><mo>∞</mo><mi mathvariant="normal">π</mi><mo> </mo></math></p>"
Expected Result :
Result which I get :

The textField does not support MathML, it only support very basic html nor can you use the html component since the JEditorPane on which it's built neither does support MathML
You will need an external library as for example jeuclid, once that you have this library in classpath you can render the xml to a BufferedImage using Converter.render and then display it in jasper report.
This can be done without a java helper class as in this example, hence writting all the code directly in the jrxml on 1 line (using the builder pattern below), but for clarity of example I'm will use external helper class.
Example
java
public class MathML {
public static BufferedImage getImage(String xml, float size) throws IOException, SAXException, ParserConfigurationException {
// Load the string to a node
Element node = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)))
.getDocumentElement();
//Generate the layout parameter
MutableLayoutContext params = new LayoutContextImpl(
LayoutContextImpl.getDefaultLayoutContext());
params.setParameter(Parameter.MATHSIZE, size);
//Render the xml to a BufferedImage
return Converter.getInstance().render(node, params);
}
}
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="Blank_A4_12" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="8deaea2e-3739-4c4e-b2b5-8c58773ab1a0">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<queryString>
<![CDATA[]]>
</queryString>
<title>
<band height="50" splitType="Stretch">
<image>
<reportElement x="0" y="0" width="100" height="50" uuid="9ee17167-a91e-4725-b36e-a4bba5e24acb">
</reportElement>
<imageExpression><![CDATA[it.jdd.MathML.getImage("<math xmlns='http://www.w3.org/1998/Math/MathML'><mi>A</mi><mo>+</mo><mo> </mo><mi>B</mi><mo> </mo><mo> </mo><msqrt><mi>c</mi><mfenced><mrow><mi>d</mi><mfenced open='[' close=']'><mi>r</mi></mfenced></mrow></mfenced></msqrt><mo> </mo><mi>δ</mi><mo> </mo><mo>∞</mo><mi mathvariant='normal'>π</mi><mo> </mo></math>",70f)]]></imageExpression>
</image>
</band>
</title>
</jasperReport>
Output (export to pdf)

Related

Some currency Symbol in Jasper report is not coming

I have created a jasper report template using jaspersoft studio and I am populating the template using java code. I have some data in the report which needs to be localize and for that I am seeting the "locale" by below code in java.
Locale locale = new Locale("zh", "CN");
templateParameters.put("REPORT_LOCALE", locale); //A map to pass to report
I have also tried -
Locale locale = java.util.Locale.CHINA;
In populated report "Number formatting" is there but currecny symbol is missing(only dollar, pound, euro symbols are coming)
Below is the code I have used in jasper report to populate the text field -
NumberFormat.getCurrencyInstance($P{REPORT_LOCALE}).format($P{Param_Name})
I would be very thankful if someone could pointout the mistake or provide some suggestion.
I believe that your issue related with font supporting.
We should use Font Extensions in case using JRPdfExporter.
I tried to use font with Chinese support and in this case everything is OK.I don't know why using a ton of another fonts is not helping
Example
Java code
Map<String, Object> params = new HashMap<>();
params.put(JRParameter.REPORT_LOCALE, Locale.CHINA);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, new JREmptyDataSource());
Report template
There are 4 textFields in jrxml file: two using font with Chinese support and another 2 - without it.
<?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="Show currency" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<parameter name="value" class="java.lang.Double" isForPrompting="false">
<defaultValueExpression><![CDATA[1234.567]]></defaultValueExpression>
</parameter>
<title>
<band height="70">
<textField>
<reportElement x="10" y="10" width="300" height="15"/>
<textElement>
<font fontName="Sharp Dawn"/>
</textElement>
<textFieldExpression><![CDATA[NumberFormat.getCurrencyInstance(new Locale("zh", "CN")).format($P{value})]]></textFieldExpression>
</textField>
<textField>
<reportElement x="10" y="25" width="300" height="15"/>
<textElement>
<font fontName="Sharp Dawn"/>
</textElement>
<textFieldExpression><![CDATA[NumberFormat.getCurrencyInstance($P{REPORT_LOCALE}).format($P{value})]]></textFieldExpression>
</textField>
<textField>
<reportElement x="3" y="40" width="300" height="15"/>
<textFieldExpression><![CDATA[NumberFormat.getCurrencyInstance($P{REPORT_LOCALE}).format($P{value})]]></textFieldExpression>
</textField>
<textField>
<reportElement x="3" y="55" width="300" height="15"/>
<textFieldExpression><![CDATA[NumberFormat.getCurrencyInstance(new Locale("zh", "CN")).format($P{value})]]></textFieldExpression>
</textField>
</band>
</title>
</jasperReport>
Output result
The pdf file generated with help of JRPdfExporter looks like
The Yuan symbol is showing only for first group.

Jasperreport - send list of objects from Java application

I have a Java class with two attribute id (integer) and name (string). I have created a list of objects and I want to use the JasperReports to make a pdf file.
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(conceptsList,true);
Map jasperParameters = new HashMap();
jasperParameters.put("Concepts", ds);
String input = "C:/report.jasper";
JasperPrint jp = JasperFillManager.fillReport(input, jasperParameters, new JREmptyDataSource());
JasperExportManager.exportReportToPdfFile(jp, "C:/report.pdf");
In iReport Designer I have one parameter (Concepts) and set net.sf.jasperreports.engine.data.JRBeanCollectionDataSource as a parameter class. I also define two fields id and name and put them in the details band. but my pdf file does not show anything. I think somewhere I have to define datasource for id and name but I cannot find anything. It would be great if anyone can help me.
<?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="report22" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="313d6b25-bcea-43a0-80db-2c7733499ca2">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<parameter name="Concepts" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="id" class="java.lang.Integer"/>
<field name="name" class="java.lang.String"/>
<title>
<band height="50" splitType="Stretch"/>
</title>
<detail>
<band height="200" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="100" height="20" uuid="b6c2dc20-ebaa-4dfe-8d42-b8318bf05d33"/>
<textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="100" y="0" width="100" height="20" uuid="fbc83087-e178-4210-a9f0-a8e1d86a5f71"/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</band>
</detail>
You can send the object data as a datasource to JRXML. Additionally, if the List should also be sent as a datasource to JRXML.
First design the iReport to accept Object as datasource:
1) Add the project "src" in class-path in iReport.
2) Specify the object package.className in JRXML report datasource.
3) Map the TextFields with the Object parameters.
Now in source code, use "JRBeanCollectionDataSource" Class for sending the List of Object in "JasperFillManager.fillReport()", for Connection.
Hope this helps.

how i can modify xml field value by sax parser

hi i am very new to Xml parsing
i want to change following attribute values frequently ...........
columnCount, width and height
After that i need to rewrite xml file with modified data
in following xml file by using java(sax ,Dom or jaxB parser) please any one can give some suggestion on it...............
=======================================================================================
<?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="Hello_subreport1_subreport1" language="groovy" columnCount="2" printOrder="Horizontal" pageWidth="520" pageHeight="802" columnWidth="260" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="ac19d62f-eac8-428e-8e0a-9011534189ed">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="subjectName" class="java.lang.String">
<fieldDescription><![CDATA[subjectName]]></fieldDescription>
</field>
<field name="subjectID" class="java.lang.Integer">
<fieldDescription><![CDATA[subjectID]]></fieldDescription>
</field>
<field name="maxMarks" class="java.lang.Integer">
<fieldDescription><![CDATA[maxMarks]]></fieldDescription>
</field>
<field name="redMarks" class="java.lang.Float">
<fieldDescription><![CDATA[redMarks]]></fieldDescription>
</field>
<field name="passMarks" class="java.lang.Integer">
<fieldDescription><![CDATA[passMarks]]></fieldDescription>
</field>
<field name="marks" class="java.lang.Float">
<fieldDescription><![CDATA[marks]]></fieldDescription>
</field>
<background>
<band splitType="Stretch"/>
</background>
<detail>
<band height="52">
<textField isStretchWithOverflow="true">
<reportElement uuid="5f7665fb-9218-4434-a9e5-5eff306499b3" x="0" y="33" width="100" height="20"/>
<box>
<pen lineWidth="0.0"/>
<topPen lineWidth="0.0"/>
<leftPen lineWidth="0.0"/>
<bottomPen lineWidth="0.0"/>
<rightPen lineWidth="0.0"/>
</box>
<textElement>
<font size="12"/>
</textElement>
<textFieldExpression><![CDATA[$F{marks}]]></textFieldExpression>
</textField>
<textField>
<reportElement uuid="6b999cb1-600e-4634-be8f-7ac99e225f49" x="0" y="13" width="100" height="20"/>
<box>
<topPen lineWidth="0.25"/>
</box>
<textElement/>
<textFieldExpression><![CDATA[$F{subjectName}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
========================================================================
If you want to modify the document them use a DOM parser. This will transform the xml file into a datastructure where you can find the attributes and change their values. Have a look at jdom or dom4j, they are really easy to use.
A sax parser is a good choice if you only want to read the document. That parser just creates events while parsing the document.
Answering to your comment: I do not get a NPE but the rootNode.getChild("detail")) return null. That is because the element is associated with a namespace. Replace the last line in your sample code with
System.out.println(rootNode.getChild("detail", rootNode.getNamespace()));
That works.
there are tons of documents on web detailing editing of an XML. Explore them and then try something out. If you are stuck then post it here.
some ref: http://www.w3schools.com/dom/default.asp
How to modify XML data in Dom parser
http://www.mkyong.com/java/how-to-modify-xml-file-in-java-dom-parser/
http://www.drdobbs.com/jvm/easy-dom-parsing-in-java/231002580
Maybe you could use avc-binding-dom, which binds DOM nodes to your custom Java interface via annotations:
import org.w3c.dom.Node;
import net.avcompris.binding.annotation.XPath;
import net.avcompris.binding.dom.impl.DefaultDomBinder;
#Namespaces("xmlns:jr=http://jasperreports.sourceforge.net/jasperreports")
#XPath("/jr:jasperReport")
interface MyJasperReport {
#XPath("#columnCount")
int getColumnCount();
void setColumnCount(int columnCount);
#XPath("#pageWidth")
int getPageWidth();
void setPageWidth(int pageWidth);
#XPath("jr:property[#name = 'ireport.zoom']/#value")
String getZoom();
void setZoom(String zoom);
}
Node node = ... // You have to load the XML file into a DOM node.
MyJasperReport jr = new DefaultDomBinder().bind(node, MyJasperReport.class);
jr.setColumnCount(4); // previously: 2
jr.setPageWidth(1024); // previously: 520
jr.setZoom("1.45"); // previously: "1.0"
... // then save the DOM node into a XML file.

Abort Jasper report generation on NullPointerException

I'm creating reports with Jasper Reports (4.0.0) for our project (JRE 1.6.x).
I'm getting bothered with NullPointerExceptions in my scriptlets, as they do not cause the report to abort, they just make the field be silently evaluated to null. As far as I tested, it happens only to NPE's.
The generated reports are quite important and should not have any errors. So, if an exception occurs (like NPE's for some missing data), it should stop the generation, and the database and/or report should be fixed. Such behavior may hide some report coding errors, unless someone spots the missing field.
What is the reason for this behavior with NPE's? Is there any compilation option or execution flag I can switch to make NPE's bubble up as other exceptions do?
I really wish I won't have to wrap every scriptlet method in a try..catch block and throw another exception on NPE's.
Thanks!
Ok, a sample report. It does not uses scriptlets, but generate the NPE directly on a field evaluation (the result is the same), and can be executed directly on iReport preview without parameters:
<?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="NPE_Report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<variable name="NullVariable" class="java.lang.Integer" calculation="System">
<initialValueExpression><![CDATA[null]]></initialValueExpression>
</variable>
<variable name="NotNullVariable" class="java.lang.Integer" calculation="System">
<initialValueExpression><![CDATA[200]]></initialValueExpression>
</variable>
<title>
<band height="72" splitType="Stretch">
<staticText>
<reportElement x="11" y="10" width="179" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<text><![CDATA[Successful field evaluation:]]></text>
</staticText>
<textField>
<reportElement x="190" y="10" width="296" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["0x"+Integer.toHexString($V{NotNullVariable}.intValue()+55)]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="11" y="32" width="179" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<text><![CDATA[NPE on field evaluation:]]></text>
</staticText>
<textField>
<reportElement x="190" y="32" width="296" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["0x"+Integer.toHexString($V{NullVariable}.intValue()+55)]]></textFieldExpression>
</textField>
</band>
</title>
<detail>
<band height="24" splitType="Stretch"/>
</detail>
</jasperReport>
It doesn't sound like a null pointer expression problem. It sounds like your data source allows null fields. JasperReports is robust enough to handle a report where some information is missing. There is a property you can set so that when information is missing the field prints "null" or is left blank. If you don't want the report to generate at all if the data field is null, modify your data source so the fields are "not null".
Alternatively, drop on a conditional statement so that your scriptlet only runs if th fields are not null and break if they are. Then when the report hits a null field it will stop.

Blank PDF even with the simplest Jasperreport jrxml

i have a EJB site with glassfish 3.1 + JSF for jasperreport 4.0.1. the site has no problem on streaming pdf, but it products blank PDF while printing PDF with runReportToPdfStream, below is the code snippet:
EJB
public class BookEJB {
public void printReport() throws ClassNotFoundException, IOException, JRException {
Map parameterMap = new HashMap();
FacesContext ctx = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) ctx.getExternalContext().getResponse();
InputStream reportStream = ctx.getExternalContext().getResourceAsStream("/reports/test.jasper");
ServletOutputStream servletOutputStream = response.getOutputStream();
servletOutputStream.flush();
response.setContentType("application/pdf");
JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parameterMap);
servletOutputStream.flush();
servletOutputStream.close();
ctx.responseComplete();
}}
test.jrxml - a simple report without SQL connection
<?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="test" pageWidth="800" pageHeight="1200" columnWidth="555" leftMargin="25" rightMargin="25" topMargin="30" bottomMargin="30">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<queryString>
<![CDATA[]]>
</queryString>
<pageHeader>
<band height="100">
<staticText>
<reportElement x="0" y="0" width="285" height="36"/>
<textElement>
<font size="24" isBold="true"/>
</textElement>
<text><![CDATA[Report of Testing]]></text>
</staticText>
</band>
</pageHeader>
<detail>
<band height="200">
<staticText>
<reportElement x="0" y="0" width="374" height="48"/>
<textElement>
<font size="18"/>
</textElement>
<text><![CDATA[If you don't see this, it didn't work blah blah blah.... ]]></text>
</staticText>
</band>
</detail>
<pageFooter>
<band height="100"/>
</pageFooter>
</jasperReport>
no error log in glassfish when generating this report on JSF, but only blank PDF has been shown. Please help, let me know if you need further info for the analysis.
Steven
After all, JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parameterMap, new JREmptyDataSource()); solved the problem.
Quote from Sanda of Jasperreport:
By default, when no datasource info is present in a report, JR generates no pages. Another option (which can be set in the report's whenNoDataType attribute) would be to print all report sections, excepting the <detail>.
This report contains a detail section, but only with some static data. To ensure this section will be printed too, the simplest way is to provide an empty data source, containing a single empty record.
Source: https://community.jaspersoft.com/questions/537650/blank-pdf-even-simplest-jrxml
When you are not using the details band, just static values, you can do the following:
Right click in the iReport project, then select 'Properties', search for the property 'When no Data', and select 'All Sections, No Detail'
It works for me, using iReport 4.0
In addition to what Mythox said, I'll show the best way to fake a data source in jasper and if you need also on JasperServer.
1) Define an Empty Data Adapter (a simple .xml file), and deploy it in Server or put it in reports folder:
<?xml version="1.0" encoding="UTF-8" ?><emptyDataAdapter class="net.sf.jasperreports.data.empty.EmptyDataAdapterImpl"><name>Nuovo Data Adapter 1</name><recordCount>1</recordCount></emptyDataAdapter>
2) Link it into the main report:
<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="repor" language="javascript" pageWidth="612" pageHeight="792" whenNoDataType="NoDataSection" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isFloatColumnFooter="true" uuid="c0eee90e-1b1a-4f34-ad99-1112847752de">
<property name="net.sf.jasperreports.data.adapter" value="EmptyDataAdapter.xml"/>
prefix "repo:" to the value of the property for the data adapter, if the xml is deployed on jasper server.
The attribute "whenNoDataType" will be ignored.
Other details here.

Categories

Resources