Membuat subreport Jasper dalam SpringMVC
Pada artikel ini, kita akan membuat implementasi download file PDF/XLS dari aplikasi web. Fitur ini akan kita implementasi menggunakan library Jasper Report dan framework Spring MVC.
Projectnya akan kita buat menggunakan Maven, supaya bisa dibuka dengan baik (portable) di berbagai IDE. Untuk bisa memahami artikel ini dengan baik, pembaca harus sudah paham tentang Spring Framework dan Spring MVC. Yang belum paham Spring Framework bisa membaca artikel terdahulu tentang Dependency Injection. Sedangkan pembahasan tentang Spring MVC bisa dibaca di rangkaian artikel berseri tentang membuat aplikasi web dengan Spring MVC.
Source code lengkap dapat diakses di repository Github. Bagi yang ingin tahu urutan langkah-langkah implementasinya, bisa lihat commit history.
Setup Project
Pertama, kita setup dulu projectnya menggunakan Maven Archetype dengan perintah berikut
mvn archetype:create -DgroupId=com.muhardin.endy.belajar -DartifactId=belajar-springmvc-jasper
Kemudian konversi menjadi aplikasi web dengan cara:
- edit
pom.xml
, ganti<packaging>jar</packaging>
menjadi<packaging>war</packaging>
- tambahkan file
src/main/webapp/WEB-INF/web.xml
- ini langkah opsional, tambahkan
src/main/webapp/index.html
supaya ada halaman Hello World
Kondisi project pada tahap ini bisa dilihat di commit 1fa6134d10
Setelah selesai di tahap ini, kita bisa buka projectnya menggunakan Netbeans atau Eclipse.
Aktivasi Spring MVC
Mulai dari yang mudah dulu, kita buat controller yang menampilkan Hello World dengan Spring MVC. Ini sekedar memastikan bahwa konfigurasi Spring MVC kita sudah benar, sehingga pada waktu implementasi Jasper Report nanti kita tidak perlu lagi memusingkan error Spring MVC.
Tambahkan dependensi Spring MVC di pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
Saya menggunakan Maven properties untuk mendeklarasikan versi library. Ini akan memudahkan kalau di kemudian hari kita ingin mengupgrade versinya.
<properties>
<org.springframework.version>4.0.2.RELEASE</org.springframework.version>
</properties>
Agar bisa memproses file JSP, kita tambahkan juga library jstl
.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
<scope>runtime</scope>
</dependency>
Selanjutnya, deklarasikan DispatcherServlet
milik Spring di web.xml
<servlet>
<servlet-name>belajar</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>belajar</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Kita harus membuat file konfigurasi sesuai dengan nama servlet. Karena namanya belajar
, maka file yang harus dibuat adalah belajar-servlet.xml
. Isinya tidak banyak, seperti ini:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
<mvc:default-servlet-handler />
<context:component-scan base-package="com.muhardin.endy.belajar.springmvcjasper.controller" />
<bean id="jstlViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/templates/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Sediakan file halo.jsp
dalam folder WEB-INF/templates/jsp
. Isinya tidak saya pasang di sini, silahkan lihat sendiri di Github.
Buat controller dalam package com.muhardin.endy.belajar.springmvcjasper.controller
, sesuai konfigurasi dalam belajar-servlet.xml
. Isi file bisa dilihat di Github.
Pada tahap ini, kita bisa menjalankan aplikasinya dengan perintah mvn clean package tomcat:run
dan browse ke http://localhost:8080/belajar-springmvc-jasper/halo
Kondisi folder project pada tahap ini bisa dilihat di sini.
Aktivasi Jasper Report
Kita harus membuat dulu template reportnya. Gunakan iReport untuk mendesain template secara visual, supaya lebih mudah. Berikut screenshot report yang saya buat
Semua template Jasper Report kita simpan dalam folder src/main/webapp/WEB-INF/templates/jrxml
.
Agar bisa memproses template report tersebut, kita tambahkan dulu library Jasper Report di pom.xml
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>${jasperreports.version}</version>
<scope>runtime</scope>
</dependency>
Cukup gunakan scope runtime
karena kita tidak perlu import class Jasper di kode program kita. Tambahkan juga dependensi javax.servlet.http
supaya kita bisa menggunakan class HttpServletRequest
nantinya. Scopenya kita gunakan provided
, karena sudah disediakan dalam application server (misal: Tomcat).
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
Selanjutnya, kita tinggal isi data yang akan ditampilkan dalam dokumen PDF/XLS. Ini kita lakukan di kode program Java dalam class HaloController
. Berikut methodnya
@RequestMapping(value = "/anggota/export*", method = RequestMethod.GET)
public ModelMap exportDataAnggota(HttpServletRequest request) {
String uri = request.getRequestURI();
String format = uri.substring(uri.lastIndexOf(".") + 1);
return new ModelMap()
.addAttribute("format", format)
.addAttribute("tanggal", new Date())
.addAttribute("dataSource", service.semuaAnggota());
}
Pada kode program di atas, pertama kita ambil dulu akhiran di URL yang diakses user. Contohnya, bila user mengakses http://localhost:8080/belajar-springmvc-jasper/anggota/export.pdf
, maka variabel format
akan berisi pdf
. Variabel format
ini akan digunakan Spring untuk menentukan jenis outputnya, apakah PDF, XLS, CSV, dsb.
Kita isi variabel apapun yang kita butuhkan dalam report. Pada contoh di atas, kita kirim dua variabel yaitu tanggal
dan dataSource
. Variabel tanggal
akan menjadi parameter dalam Jasper Report, sedangkan dataSource
akan menjadi sumber data yang akan ditampilkan dalam band detail
. Untuk lebih jelasnya, silahkan buka file templatenya dengan menggunakan iReport.
Selanjutnya, kita konfigurasi Spring agar request ke url http://localhost:8080/belajar-springmvc-jasper/anggota/export.pdf
diteruskan ke Jasper Report. Kita buat deklarasi resolver untuk Jasper Report dalam belajar-servlet.xml
sebagai berikut
<bean id="jasperViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="classpath:jasper-views.xml"/>
<property name="order" value="0"/>
</bean>
Tambahkan juga property order
di konfigurasi JSP supaya dia dijalankan setelah Jasper Report.
<bean id="jstlViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/templates/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
Ini kita lakukan karena resolver JSP tidak bisa mengecek apakah templatenya ditemukan atau tidak. Dia akan langsung mengeluarkan pesan error. Dengan resolver Jasper dieksekusi duluan, maka flownya akan seperti ini:
- Dari controller terima nama view
/anggota/export.pdf
- Cari view dengan nama tersebut dalam
jasperViewResolver
- Kalau tidak ketemu lanjutkan cari dalam
jstlViewResolver
- Kalau tidak ketemu juga, keluarkan pesan error
Kondisi folder project pada tahap ini bisa dilihat di sini
Pada tahap ini kita sudah bisa menghasilkan file PDF ataupun XLS menggunakan Jasper Report dan Spring MVC. Tentunya pada aplikasi sebenarnya data diambil dari database. Tapi untuk menyederhanakan masalah agar kita bisa fokus ke konfigurasi Jasper dan Spring, maka data yang ditampilkan kita hardcode saja.
Selanjutnya, kita akan mencoba konfigurasi yang lebih sulit, yaitu sub report.
Sub Report
Subreport adalah report di dalam report. Ini adalah fitur canggih dari Jasper Report. Kita tidak akan membahas detail tentang apa itu subreport. Silahkan baca artikel ini dan ini untuk memahami apa itu subreport.
Satu report induk bisa menampung banyak subreport. Masing-masing subreport memiliki template dan dataSource
sendiri. Untuk itu, kita perlu memberitahukan pada semua pihak tentang lokasi / nama file template subreport dan nama variabel dataSource
yang digunakan di subreport.
Kita mulai dari desain template induk terlebih dulu. Ini kita lakukan di iReport. Drag and drop icon subreport di Palette ke template. iReport akan menampilkan wizard untuk membantu kita.
Saya lebih suka membuat templatenya secara terpisah, kemudian menyatukannya secara manual. Oleh karena itu, kita pilih Just create subreport element.
Hasilnya sebagai berikut.
Sebetulnya di dokumentasi Spring MVC ada penjelasan tentang cara menggunakan subreport.
Tapi sayangnya, isinya tidak nyambung sama penjelasan di atasnya. Penjelasan report sederhana dibuat menggunakan konfigurasi file properties, sedangkan penjelasan subreport dibuat menggunakan konfigurasi file XML. Perbedaannya bisa dilihat di sini atau pada gambar di bawah.
Selanjutnya, kita tambahkan parameter di desain report induk kita. Bisa menggunakan GUI ataupun langsung edit XMLnya. Kali ini saya pakai XML saja supaya bisa copy-paste
Kita tambahkan dua parameter, yaitu SubReportKantor
dan dataSourceSubreport
. Kedua parameter ini kita gunakan pada deklarasi subreport yang sudah ditambahkan iReport pada waktu kita drag and drop tadi.
Perhatikan label X
dan Y
. Itu akan kita gunakan pada konfigurasi lainnya.
Nama variabel dataSourceSubreport
yang ditandai dengan label X
kita gunakan untuk menyuplai data yang dibutuhkan subreport dari dalam kode program Java.
Selanjutnya kita edit konfigurasi Jasper Report di file jasper-views.xml
. Tambahkan lokasi template subreport dan nama variabel yang digunakan untuk dataSource
nya.
Selesai sudah. Silahkan coba akses lagi http://localhost:8080/belajar-springmvc-jasper/anggota/export.pdf
untuk melihat hasil akhirnya.
FAQ
Pada umumnya, kita semua menggunakan konfigurasi Jasper yang berbasis file properties, karena itulah yang dicontohkan di dokumentasi Spring Framework. Pada waktu muncul kebutuhan subreport, ternyata file konfigurasinya XML.
Apakah saya harus konversi semua konfigurasi properties menjadi XML ??
Jangan khawatir. Kita bisa menggunakan dua-duanya sekaligus. Tidak perlu pilih salah satu. Konfigurasi report yang lama tidak perlu dibuang/ditulis ulang menjadi xml. Cukup deklarasikan dua view resolver
, yang satu properties, satu lagi XML. Begini contohnya
<bean id="propertiesJasperViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
<property name="order" value="0"/>
</bean>
<bean id="xmlJasperViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="classpath:jasper-views.xml"/>
<property name="order" value="1"/>
</bean>
<bean id="jstlViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/templates/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="2"/>
</bean>
Dengan cara di atas, berikut flow Spring MVC dalam mencari template yang sesuai:
- Dari controller terima nama view
/anggota/export.pdf
- Cari view dengan nama tersebut dalam
propertiesJasperViewResolver
- Kalau tidak ketemu lanjutkan cari dalam
xmlJasperViewResolver
- Kalau masih tidak ketemu juga lanjutkan cari dalam
jstlViewResolver
- Kalau tidak ketemu juga, keluarkan pesan error
Demikian penjelasan tentang integrasi Spring MVC dan Jasper Report. Source code lengkap bisa diambil di Github
Semoga bermanfaat