Laporkan Scriptlets
Kita telah melihat pada bab-bab sebelumnya, data yang ditampilkan pada laporan biasanya diambil dari parameter laporan dan kolom laporan. Data ini dapat diolah menggunakan variabel laporan dan ekspresinya. Ada situasi ketika fungsionalitas kompleks tidak dapat dicapai dengan mudah menggunakan ekspresi atau variabel laporan. Contohnya mungkin manipulasi String yang kompleks, pembuatan Peta, atau Daftar objek dalam memori atau manipulasi tanggal menggunakan Java API pihak ketiga. Untuk situasi seperti itu, JasperReports memberi kita cara yang sederhana dan kuat untuk melakukan hal iniScriptlets.
Scriptlet adalah urutan kode Java yang dijalankan setiap kali terjadi peristiwa laporan. Nilai variabel laporan dapat dipengaruhi melalui scriptlet.
Deklarasi Scriptlet
Kita dapat mendeklarasikan scriptlet dengan dua cara -
Menggunakan <scriptlet> elemen. Elemen ini memiliki atribut nama dan atribut kelas . The kelas atribut harus menentukan nama kelas, yang meluas JRAbstractScriptlet kelas. Kelas harus tersedia di jalur kelas pada waktu pengisian laporan dan harus memiliki konstruktor kosong, sehingga mesin dapat membuat instance dengan cepat.
Menggunakan atribut scriptletClass dari elemen <jasperReport>, di templat laporan (JRXML). Dengan menyetel atribut ini dengan nama scriptlet yang memenuhi syarat (termasuk seluruh nama paket), kami menunjukkan bahwa kami ingin menggunakan scriptlet. Instance scriptlet, dibuat dengan atribut ini, berfungsi seperti scriptlet pertama dalam daftar scriptlet dan memiliki nama standar REPORT.
Kelas scriptlet
Scriptlet adalah kelas java, yang harus memperluas salah satu dari kelas berikut -
net.sf.jasperreports.engine.JRAbstractScriptlet- Kelas ini berisi sejumlah metode abstrak yang harus diganti dalam setiap implementasi. Metode ini dipanggil secara otomatis oleh JasperReports pada saat yang tepat. Pengembang harus menerapkan semua metode abstrak.
net.sf.jasperreports.engine.JRDefaultScriptlet- Kelas ini berisi implementasi kosong default dari setiap metode di JRAbstractScriptlet. Pengembang hanya perlu mengimplementasikan metode yang dia butuhkan untuk proyeknya.
Tabel berikut mencantumkan metode di kelas di atas. Metode ini akan dipanggil oleh mesin laporan pada waktu yang tepat, selama fase pengisian laporan.
S.NO | Metode dan Deskripsi |
---|---|
1 | public void beforeReportInit() Dipanggil sebelum inisialisasi laporan. |
2 | public void afterReportInit() Dipanggil setelah inisialisasi laporan. |
3 | public void beforePageInit() Dipanggil sebelum setiap halaman diinisialisasi. |
4 | public void afterPageInit() Dipanggil setelah setiap halaman diinisialisasi. |
5 | public void beforeColumnInit() Dipanggil sebelum setiap kolom diinisialisasi. |
6 | public void afterColumnInit() Dipanggil setelah setiap kolom diinisialisasi. |
7 | public void beforeGroupInit(String groupName) Dipanggil sebelum grup yang ditentukan dalam parameter diinisialisasi. |
8 | public void afterGroupInit(String groupName) Dipanggil setelah grup yang ditentukan dalam parameter diinisialisasi. |
9 | public void beforeDetailEval() Dipanggil sebelum setiap rekaman di bagian detail laporan dievaluasi. |
10 | public void afterDetailEval() Dipanggil setelah setiap rekaman di bagian detail laporan dievaluasi. |
Sejumlah scriptlet dapat ditentukan per laporan. Jika tidak ada scriptlet yang ditentukan untuk laporan, mesin masih membuat satu contoh JRDefaultScriptlet dan mendaftarkannya dengan parameter REPORT_SCRIPTLET bawaan.
Kami dapat menambahkan metode tambahan apa pun yang kami butuhkan ke scriptlet kami. Laporan dapat memanggil metode ini dengan menggunakan parameter built-in REPORT_SCRIPTLET.
Scriptlets Global
Kita dapat mengaitkan scriptlet dengan cara lain ke laporan, yaitu dengan mendeklarasikan scriptlet secara global. Ini membuat scriptlet berlaku untuk semua laporan yang diisi dalam penerapan JasperReports yang diberikan. Ini dipermudah oleh fakta bahwa scriptlets dapat ditambahkan ke JasperReports sebagai ekstensi. Titik ekstensi scriptlet diwakili oleh antarmuka net.sf.jasperreports.engine.scriptlets.ScriptletFactory . JasperReports akan memuat semua pabrik scriptlet yang tersedia melalui ekstensi saat runtime. Kemudian, itu akan meminta masing-masing dari mereka untuk daftar contoh scriptlet yang ingin mereka terapkan ke laporan saat ini yang sedang dijalankan. Ketika meminta daftar contoh scriptlet, mesin memberikan beberapa informasi konteks yang dapat digunakan oleh pabrik untuk memutuskan, scriptlet mana yang benar-benar berlaku untuk laporan saat ini.
Laporkan Gubernur
Gubernur hanyalah perpanjangan dari scriptlet global yang memungkinkan kami untuk mengatasi masalah mesin laporan yang memasuki loop tak terbatas pada waktu proses, sambil membuat laporan. Template laporan yang tidak valid tidak dapat dideteksi pada waktu desain, karena sebagian besar waktu, kondisi untuk memasuki loop tak terbatas bergantung pada data aktual yang dimasukkan ke mesin pada waktu proses. Laporan Gubernur membantu dalam memutuskan apakah laporan tertentu telah memasuki putaran tak terbatas dan mereka dapat menghentikannya. Ini mencegah kehabisan sumber daya untuk mesin yang menjalankan laporan.
JasperReports memiliki dua pengatur laporan sederhana yang akan menghentikan eksekusi laporan berdasarkan jumlah halaman maksimum yang ditentukan atau interval waktu tunggu yang ditentukan. Mereka adalah -
net.sf.jasperreports.governors.MaxPagesGovernor- Ini adalah skrip global yang mencari dua properti konfigurasi untuk memutuskan apakah ini berlaku atau tidak untuk laporan yang sedang dijalankan. Properti konfigurasi adalah -
net.sf.jasperreports.governor.max.pages.enabled=[true|false]
net.sf.jasperreports.governor.max.pages=[integer]
net.sf.jasperreports.governors.TimeoutGovernor- Ini juga skrip global yang mencari dua properti konfigurasi berikut untuk memutuskan apakah itu berlaku atau tidak.
Properti konfigurasi adalah -
net.sf.jasperreports.governor.timeout.enabled=[true|false]
net.sf.jasperreports.governor.timeout=[milliseconds]
Properti untuk kedua gubernur dapat disetel secara global, di file jasperreports.properties, atau di tingkat laporan, sebagai properti laporan kustom. Ini berguna karena laporan yang berbeda dapat memiliki perkiraan ukuran atau batas waktu tunggu yang berbeda dan juga karena Anda mungkin ingin mengaktifkan gubernur untuk semua laporan, sementara menonaktifkannya untuk beberapa, atau sebaliknya.
Contoh
Mari menulis kelas scriptlet (MyScriptlet). Isi file C: \ tools \ jasperreports-5.0.1 \ test \ src \ com \ tutorialspoint \ MyScriptlet.java adalah sebagai berikut -
package com.tutorialspoint;
import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRScriptletException;
public class MyScriptlet extends JRDefaultScriptlet {
public void afterReportInit() throws JRScriptletException{
System.out.println("call afterReportInit()");
// this.setVariableValue("AllCountries", sbuffer.toString());
this.setVariableValue("someVar", new String("This variable value
was modified by the scriptlet."));
}
public String hello() throws JRScriptletException {
return "Hello! I'm the report's scriptlet object.";
}
}
Rincian kelas scriptlet di atas adalah sebagai berikut -
Dalam metode afterReportInit , kami menetapkan nilai ke variabel"someVar" this.setVariableValue ("someVar", String baru ("Nilai variabel ini telah diubah oleh scriptlet.")).
Di akhir kelas, metode tambahan dipanggil 'hello'telah ditentukan. Ini adalah contoh metode yang dapat ditambahkan ke Scriptlet yang benar-benar mengembalikan nilai, daripada menyetel Variabel.
Selanjutnya, kita akan menambahkan referensi kelas scriptlet di templat laporan yang ada ( Desain Laporan Bab ). Template laporan yang direvisi (jasper_report_template.jrxml) adalah sebagai berikut. Simpan ke direktori C: \ tools \ jasperreports-5.0.1 \ test -
<?xml version = "1.0"?>
<!DOCTYPE jasperReport PUBLIC
"//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<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 = "jasper_report_template" pageWidth = "595"
pageHeight = "842" columnWidth = "515"
leftMargin = "40" rightMargin = "40" topMargin = "50" bottomMargin = "50"
scriptletClass = "com.tutorialspoint.MyScriptlet">
<style name = "alternateStyle" fontName = "Arial" forecolor = "red">
<conditionalStyle>
<conditionExpression>
<![CDATA[new Boolean($V{countNumber}.intValue() % 2 == 0)]]>
</conditionExpression>
<style forecolor = "blue" isBold = "true"/>
</conditionalStyle>
</style>
<parameter name = "ReportTitle" class = "java.lang.String"/>
<parameter name = "Author" class = "java.lang.String"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name = "country" class = "java.lang.String">
<fieldDescription>
<![CDATA[country]]>
</fieldDescription>
</field>
<field name = "name" class = "java.lang.String">
<fieldDescription>
<![CDATA[name]]>
</fieldDescription>
</field>
<variable name = "countNumber" class = "java.lang.Integer"
calculation = "Count">
<variableExpression><
![CDATA[Boolean.TRUE]]>
</variableExpression>
</variable>
<variable name = "someVar" class = "java.lang.String">
<initialValueExpression>
<![CDATA["This is the initial variable value."]]>
</initialValueExpression>
</variable>
<title>
<band height = "100">
<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">
<![CDATA[$P{ReportTitle}]]>
</textFieldExpression>
<anchorNameExpression>
<![CDATA["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">
<![CDATA[$P{Author}]]>
</textFieldExpression>
</textField>
<textField isBlankWhenNull = "true">
<reportElement x = "0" y = "50" width = "515"
height = "30" forecolor = "#993300"/>
<textElement textAlignment = "Center">
<font size = "10"/>
</textElement>
<textFieldExpression class = "java.lang.String">
<![CDATA[$V{someVar}]]>
</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>
<![CDATA[]]>
</text>
</staticText>
<staticText>
<reportElement x = "414" y = "3" width = "121" height = "15" />
<textElement textAlignment = "Center" verticalAlignment = "Middle">
<font isBold = "true" />
</textElement>
<text><![CDATA[Country]]></text>
</staticText>
<staticText>
<reportElement x = "0" y = "3" width = "136" height = "15" />
<textElement textAlignment = "Center" verticalAlignment = "Middle">
<font isBold = "true" />
</textElement>
<text><![CDATA[Name]]></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>
<![CDATA[]]>
</text>
</staticText>
<textField>
<reportElement style = "alternateStyle" x="414" y = "0"
width = "121" height = "15" />
<textElement textAlignment = "Center" verticalAlignment = "Middle">
<font size = "9" />
</textElement>
<textFieldExpression class = "java.lang.String">
<![CDATA[$F{country}]]>
</textFieldExpression>
</textField>
<textField>
<reportElement x = "0" y = "0" width = "136" height = "15" />
<textElement textAlignment = "Center" verticalAlignment = "Middle" />
<textFieldExpression class = "java.lang.String">
<![CDATA[$F{name}]]>
</textFieldExpression>
</textField>
</band>
</detail>
<summary>
<band height = "45">
<textField isStretchWithOverflow = "true">
<reportElement x = "0" y = "10" width = "515" height = "15" />
<textElement textAlignment = "Center"/>
<textFieldExpression class = "java.lang.String">
<![CDATA["There are " + String.valueOf($V{REPORT_COUNT}) +
" records on this report."]]>
</textFieldExpression>
</textField>
<textField isStretchWithOverflow = "true">
<reportElement positionType = "Float" x = "0" y = "30" width = "515"
height = "15" forecolor = "# 993300" />
<textElement textAlignment = "Center">
<font size = "10"/>
</textElement>
<textFieldExpression class = "java.lang.String">
<![CDATA[$P{REPORT_SCRIPTLET}.hello()]]>
</textFieldExpression>
</textField>
</band>
</summary>
</jasperReport>
Rincian template laporan yang direvisi diberikan di bawah ini -
Kami telah mereferensikan kelas MyScriptlet dalam atribut scriptletClass dari elemen <jasperReport>.
Scriptlet hanya dapat mengakses, tetapi tidak dapat mengubah kolom dan parameter laporan. Namun, scriptlet dapat mengubah nilai variabel laporan. Ini bisa dilakukan dengan memanggil metode setVariableValue (). Metode ini didefinisikan dalam kelas JRAbstractScriptlet, yang selalu merupakan kelas induk dari scriptlet apa pun. Di sini, kami telah menetapkan variabel someVar , yang akan dimodifikasi oleh MyScriptlet agar memiliki nilai Nilai ini telah diubah oleh scriptlet .
Template laporan di atas memiliki pemanggilan metode dalam pita Ringkasan yang mengilustrasikan cara menulis metode baru (dalam scriptlets) dan menggunakannya dalam templat laporan. ($P{REPORT_SCRIPTLET}.hello())
Kode java untuk pengisian laporan tetap tidak berubah. Isi fileC:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java seperti yang diberikan di bawah ini -
package com.tutorialspoint;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
public class JasperReportFill {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
String sourceFileName =
"C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";
DataBeanList DataBeanList = new DataBeanList();
ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();
JRBeanCollectionDataSource beanColDataSource = new
JRBeanCollectionDataSource(dataList);
Map parameters = new HashMap();
/**
* Passing ReportTitle and Author as parameters
*/
parameters.put("ReportTitle", "List of Contacts");
parameters.put("Author", "Prepared By Manisha");
try {
JasperFillManager.fillReportToFile(
sourceFileName, parameters, beanColDataSource);
} catch (JRException e) {
e.printStackTrace();
}
}
}
Isi file POJO C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java seperti yang diberikan di bawah ini -
package com.tutorialspoint;
public class DataBean {
private String name;
private String country;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Isi file C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java seperti yang diberikan di bawah ini -
package com.tutorialspoint;
import java.util.ArrayList;
public class DataBeanList {
public ArrayList<DataBean> getDataBeanList() {
ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();
dataBeanList.add(produce("Manisha", "India"));
dataBeanList.add(produce("Dennis Ritchie", "USA"));
dataBeanList.add(produce("V.Anand", "India"));
dataBeanList.add(produce("Shrinath", "California"));
return dataBeanList;
}
/**
* This method returns a DataBean object,
* with name and country set in it.
*/
private DataBean produce(String name, String country) {
DataBean dataBean = new DataBean();
dataBean.setName(name);
dataBean.setCountry(country);
return dataBean;
}
}
Pembuatan Laporan
Kami akan mengkompilasi dan mengeksekusi file di atas menggunakan proses build ANT reguler kami. Isi dari file build.xml (disimpan di bawah direktori C: \ tools \ jasperreports-5.0.1 \ test) seperti yang diberikan di bawah ini.
File impor - baseBuild.xml diambil dari bab Pengaturan Lingkungan dan harus ditempatkan di direktori yang sama dengan build.xml.
<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
<import file = "baseBuild.xml" />
<target name = "viewFillReport" depends = "compile,compilereportdesing,run"
description = "Launches the report viewer to preview
the report stored in the .JRprint file.">
<java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
<arg value = "-F${file.name}.JRprint" />
<classpath refid = "classpath" />
</java>
</target>
<target name = "compilereportdesing" description = "Compiles the JXML file and
produces the .jasper file.">
<taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
<classpath refid = "classpath" />
</taskdef>
<jrc destdir = ".">
<src>
<fileset dir = ".">
<include name = "*.jrxml" />
</fileset>
</src>
<classpath refid = "classpath" />
</jrc>
</target>
</project>
Selanjutnya, buka jendela baris perintah dan buka direktori tempat build.xml ditempatkan. Terakhir, jalankan perintahant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport adalah target default) sebagai -
C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml
clean-sample:
[delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
[delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
[delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint
compile:
[mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
[javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
warning: 'includeantruntime' was not set, defaulting to bu
[javac] Compiling 4 source files to C:\tools\jasperreports-5.0.1\test\classes
compilereportdesing:
[jrc] Compiling 1 report design files.
[jrc] log4j:WARN No appenders could be found for logger
(net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
[jrc] log4j:WARN Please initialize the log4j system properly.
[jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
[jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.
run:
[echo] Runnin class : com.tutorialspoint.JasperReportFill
[java] log4j:WARN No appenders could be found for logger
(net.sf.jasperreports.extensions.ExtensionsEnvironment).
[java] log4j:WARN Please initialize the log4j system properly.
[java] call afterReportInit()
[java] call afterReportInit()
viewFillReport:
[java] log4j:WARN No appenders could be found for logger
(net.sf.jasperreports.extensions.ExtensionsEnvironment).
[java] log4j:WARN Please initialize the log4j system properly.
BUILD SUCCESSFUL
Total time: 18 minutes 49 seconds
Sebagai hasil dari kompilasi di atas, jendela JasperViewer terbuka seperti yang ditunjukkan pada layar di bawah ini -
Di sini kita melihat dua pesan ditampilkan dari kelas MyScriptlet -
- Di bagian judul - Nilai variabel ini telah dimodifikasi oleh scriptlet
- Di bagian bawah - Halo! Saya adalah objek scriptlet laporan.