Working with JasperReports for easy report generation
2016-06-17 16:14
671 查看
转自:http://www.jcombat.com/spring/working-with-jasperreports-for-easy-report-generation
JasperReports is a Java
based open source report generating engine. It has great dynamic report generating capabilities that can be added to any Java based application. I have a very simple demo to show how it works.
I have created a link somewhere in my application and on the click of it, I see a pop-up window with the report PDF embedded within.
To start with, we need a .jrxml template
that is externalized and every time the link is clicked, the.jrxml template
is dynamically compiled to generate a .jasper file
at the same external file location. So the first and foremost step is to prepare the mark-up for the report template, which can be easily designed using the iReport tool. The tool finally generates the .jrxml file
based on the design. The standard JasperReport template has the following layout in the same order:
Fine, now let’s assume, I have my .jrxml file generated and looks something like:
I keep the above .jrxml file
to some externalised location, let it be, D:/Documents/
Create a sample POJO, with two instance variables for subject name and marks, as:
DataMarksBean.java
Create another class DataBeanMarksList.java, which generates a collection of java bean objects to be used for report generation. This class looks something like:DataBeanMarksList.java
Now you need to create a method in the controller of your Spring MVC application, that actually serves the purpose of report generation. I give it some mapping as /jasper
Almost done, create a link somewhere on the landing page in your application as:
Male sure you include the following javascript function as well into your application:
Finally, clicking on the link, shows up the report PDF in a new pop-up window as:
If you need the same report to be exported to HTML, just modify the above controller method and add the following:
Add a new method renderHtml as:
So we have several points worth noting:
The .jasper file is not kept
anywhere in the JVM for any subsequent PDF generation and for now, is generated every time the link is clicked.
As expected, if we modify the .jrxml template,
it reflects instantly at runtime and we do not require any java changes, hence no build/deploy needed.
As per the documentation available for JasperReports, “Even though all its reporting functionality is available in this single JAR file (jasperreports-5.0.1.jar),
JasperReports relies on other third-party libraries for related required functionality like XML parsing, logging, and PDF generation.”
To avoid performance hit on the application because of the .jrxml file
being compiled again and again, I suggest following options to restrict the subsequent compilations:
We can keep the .jasper file in cache and
generate the .jasper soon after
the cache expires.
We can also check for the existing .jasper file
at the respective externalized location. If it doesn’t exist, compile, else not.
We can build a utility to explicitly compile the .jrxml template,
generate the .jasper file and
copy it to the respective externalized location.
JasperReports is a Java
based open source report generating engine. It has great dynamic report generating capabilities that can be added to any Java based application. I have a very simple demo to show how it works.
I have created a link somewhere in my application and on the click of it, I see a pop-up window with the report PDF embedded within.
To start with, we need a .jrxml template
that is externalized and every time the link is clicked, the.jrxml template
is dynamically compiled to generate a .jasper file
at the same external file location. So the first and foremost step is to prepare the mark-up for the report template, which can be easily designed using the iReport tool. The tool finally generates the .jrxml file
based on the design. The standard JasperReport template has the following layout in the same order:
1234567 | <title><pageHeader><columnHeader><detail><columnFooter><pageFooter><summary> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | <!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"> <jasperReport xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="jasper_report_template" language="groovy" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <parameter name="ReportTitle" class="java.lang.String"/> <parameter name="Author" class="java.lang.String"/> <queryString></queryString> <field name="subjectName" class="java.lang.String"> <fieldDescription>subjectName</fieldDescription> </field> <field name="marks" class="java.math.BigDecimal"> <fieldDescription>marks</fieldDescription> </field> <title> <band height="70"> <line> <reportElement x="0" y="0" width="515" height="1"/> </line> <textField isBlankWhenNull="true" bookmarkLevel="1"> <reportElement x="0" y="10" width="515" height="30"/> <textElement textAlignment="Center"> <font size="22"/> </textElement> <textFieldExpression class="java.lang.String">$P{ReportTitle}</textFieldExpression> <anchorNameExpression>"Title"</anchorNameExpression> </textField> <textField isBlankWhenNull="true"> <reportElement x="0" y="40" width="515" height="20"/> <textElement textAlignment="Center"> <font size="10"/> </textElement> <textFieldExpression class="java.lang.String">$P{Author}</textFieldExpression> </textField> </band> </title> <columnHeader> <band height="23"> <staticText> <reportElement mode="Opaque" x="0" y="3" width="535" height="15" backcolor="#70A9A9"/> <box> <bottomPen lineWidth="1.0" lineColor="#CCCCCC"/> </box> <textElement/> <text></text> </staticText> <staticText> <reportElement x="414" y="3" width="121" height="15"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font isBold="true"/> </textElement> <text>Marks</text> </staticText> <staticText> <reportElement x="0" y="3" width="136" height="15"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font isBold="true"/> </textElement> <text>Subject</text> </staticText> </band> </columnHeader> <detail> <band height="16"> <staticText> <reportElement mode="Opaque" x="0" y="0" width="535" height="14" backcolor="#E5ECF9"/> <box> <bottomPen lineWidth="0.25" lineColor="#CCCCCC"/> </box> <textElement/> <text></text> </staticText> <textField> <reportElement x="414" y="0" width="121" height="15"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font size="9"/> </textElement> <textFieldExpression class="java.lang.String">$F{subjectName}</textFieldExpression> </textField> <textField> <reportElement x="0" y="0" width="136" height="15"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <textFieldExpression class="java.lang.String">$F{marks}</textFieldExpression> </textField> </band> </detail> <columnFooter> <band height="200"> <barChart> <chart evaluationTime="Report"> <reportElement x="0" y="0" width="555" height="200"/> <chartTitle> <titleExpression>"My First JR Bar Chart"</titleExpression> </chartTitle> </chart> <categoryDataset> <dataset incrementType="None"/> <categorySeries> <seriesExpression>$F{subjectName}</seriesExpression> <categoryExpression>$F{subjectName}</categoryExpression> <valueExpression>$F{marks}</valueExpression> </categorySeries> </categoryDataset> <barPlot isShowTickMarks="false"> <plot/> </barPlot> </barChart> </band> </columnFooter> <pageFooter> <band height="400" splitType="Stretch"> <pieChart> <chart evaluationTime="Report"> <reportElement x="135" y="0" width="270" height="300"/> <chartTitle> <titleExpression>"My First JR Pie Chart"</titleExpression> </chartTitle> </chart> <pieDataset> <dataset incrementType="None"/> <keyExpression>$F{subjectName}</keyExpression> <valueExpression>$F{marks}</valueExpression> </pieDataset> <piePlot> <plot/> <itemLabel/> </piePlot> </pieChart> </band> </pageFooter> </jasperReport> |
to some externalised location, let it be, D:/Documents/
Create a sample POJO, with two instance variables for subject name and marks, as:
DataMarksBean.java
12345678910111213141516171819202122 | package com.jcombat.beans; public class DataMarksBean { private String subjectName; private Integer marks; public String getSubjectName() { return subjectName; } public void setSubjectName(String subjectName) { this.subjectName = subjectName; } public Integer getMarks() { return marks; } public void setMarks(Integer marks) { this.marks = marks; }} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package com.jcombat.bo; import java.util.ArrayList; public class DataBeanMarksList { public ArrayList<DataMarksBean> getDataBeanList() { ArrayList<DataMarksBean> dataBeanList = new ArrayList<DataMarksBean>(); dataBeanList.add(produce("English", 58)); dataBeanList.add(produce("SocialStudies", 68)); dataBeanList.add(produce("Maths", 38)); dataBeanList.add(produce("Hindi", 88)); dataBeanList.add(produce("Scince", 78)); return dataBeanList; } /* * This method returns a DataBean object, with subjectName and marks set * in it. */ private DataMarksBean produce(String subjectName, Integer marks) { DataMarksBean dataBean = new DataMarksBean(); dataBean.setSubjectName(subjectName); dataBean.setMarks(marks); return dataBean; } } |
123456789101112131415161718192021222324252627282930313233343536373839 | @RequestMapping(value = "/jasper")public void generatePDFJasperChart(HttpServletRequest request, HttpServletResponse response) throws IOException { String sourceFileName = "D://Documents/jasper_report_template.jrxml"; System.out.println(sourceFileName); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("ReportTitle", "Jasper Demo"); parameters.put("Author", "Prepared By jCombat"); try { System.out.println("Start compiling!!! ..."); JasperCompileManager.compileReportToFile(sourceFileName); System.out.println("Done compiling!!! ..."); sourceFileName = "D://Documents/jasper_report_template.jasper"; DataBeanMarksList DataBeanList = new DataBeanMarksList(); ArrayList<DataMarksBean> dataList = DataBeanList.getDataBeanList(); JRBeanCollectionDataSource beanColDataSource = new JRBeanCollectionDataSource( dataList); JasperReport report = (JasperReport) JRLoader .loadObjectFromFile(sourceFileName); JasperPrint jasperPrint = JasperFillManager.fillReport(report, parameters, beanColDataSource); if (jasperPrint != null) { byte[] pdfReport = JasperExportManager .exportReportToPdf(jasperPrint); response.reset(); response.setContentType("application/pdf"); response.setHeader("Cache-Control", "no-store"); response.setHeader("Cache-Control", "private"); response.setHeader("Pragma", "no-store"); response.setContentLength(pdfReport.length); response.getOutputStream().write(pdfReport); response.getOutputStream().flush(); response.getOutputStream().close(); } } catch (JRException e) { e.printStackTrace(); }} |
1 | <a href="" onclick="openNewWindowForJasperWithCharts();">Generate Report</a> |
12345 | function openNewWindowForJasperWithCharts(){ var url = "/jasper"; var strWindowFeatures = "menubar=no,location=no,width=800,height=500"; window.open(url,"_blank", "location=0,height=500,width=800");} |
If you need the same report to be exported to HTML, just modify the above controller method and add the following:
1 2 3 | if (jasperPrint != null) { renderHtml(new JRHtmlExporter(), jasperPrint, writer); } |
1 2 3 4 5 6 7 8 | public static void renderHtml(JRExporter exporter, JasperPrint print, Writer writer) throws JRException { exporter.setParameter(JRExporterParameter.JASPER_PRINT, print); exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, writer); exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE); exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "servlets/image?image="); exporter.exportReport(); } |
The .jasper file is not kept
anywhere in the JVM for any subsequent PDF generation and for now, is generated every time the link is clicked.
As expected, if we modify the .jrxml template,
it reflects instantly at runtime and we do not require any java changes, hence no build/deploy needed.
As per the documentation available for JasperReports, “Even though all its reporting functionality is available in this single JAR file (jasperreports-5.0.1.jar),
JasperReports relies on other third-party libraries for related required functionality like XML parsing, logging, and PDF generation.”
To avoid performance hit on the application because of the .jrxml file
being compiled again and again, I suggest following options to restrict the subsequent compilations:
We can keep the .jasper file in cache and
generate the .jasper soon after
the cache expires.
We can also check for the existing .jasper file
at the respective externalized location. If it doesn’t exist, compile, else not.
We can build a utility to explicitly compile the .jrxml template,
generate the .jasper file and
copy it to the respective externalized location.
相关文章推荐
- ASP.NET Core 中文文档 第二章 指南(4.5)使用 SQL Server LocalDB
- metasploit安装
- OWASP
- Asp.net Web Api开发(第三篇)自定义异常过滤器
- Asp.net自定义控件之单选、多选控件
- Asp.net自定义控件之加载层
- 史上最全的ASP.NET MVC路由配置
- 史上最全的ASP.NET MVC路由配置
- MiniUI支持ASP.NET MVC
- MiniUI支持ASP.NET WebService
- ms14-068之metasploit应用
- metasploit用法案例
- AspJpeg使用 .
- extjs+asp.net mvc加载viewport.js报错?求救
- 在windows环境下使用phantomjs和casperjs的环境配置
- asp.net获取当前网址url\域名
- 教你实践ASP.NET Core Authorization(免看文档教程)
- Asp.net自定义控件之加载层
- Asp.net自定义控件之单选、多选控件
- ASP.NET框架中的数据绑定概要与数据绑定表达式的使用