Skip to main content

JasperReports | Membuat Drill Down Report Untuk Memanggil Report Lain

Sabtu kemarin, di kantor saya menyibukkan diri untuk meriset JasperReports untuk mendukung fitur drill down report, itu tuh, report yang bisa manggil report/form lain. Dalam kasus saya, saya ingin menampilkan report detail atas chart yang saya klik. Sebagai studi kasus saya ingin membuat pie chart untuk menampilkan data 5 customer dengan total penjualan terbesar, kemudian ketika bagian pie saya klik maka akan ditampilkan daftar penjualan atas customer tersebut.

Saya teringat bahwa JasperReports memiliki fitur Hyperlink, sehingga saya pun melakukan ujicoba dengan mengikuti tutorial dari hasil googling. Namun tidak ada tutorial yang memuaskan dan memenuhi kebutuhan saya, karena kebanyakan tutorial yang ada hanya menggunakan hyperlink untuk mengakses url ataupun mengarahkan report ke halaman tertentu pada report itu sendiri (misalkan hyperlink untuk mengarahkan ke halaman x).

Sedikit frustasi karena riset saya gagal, saya kembali membaca dokumentasi JasperReports pada halaman ini. Alhamdulillah saya menemukan satu keyword penting, yakni JRHyperlinkListener yang dimiliki oleh class JRViewer. (*saya bisa pulang dengan membawa satu petunjuk untuk dicoba di rumah)

Ok, sekarang kita bikin implementasi dari listener tadi untuk studi kasus yang sudah saya sebutkan di atas.

Saya membuat dua table dengan struktur sebagai berikut (*saya pengguna PostgreSQL):

CREATE TABLE bp (
bpno VARCHAR(25) NOT NULL,
bpname VARCHAR(255) NOT NULL,
CONSTRAINT pk_bp PRIMARY KEY (bpno)
);

CREATE TABLE sale (
saleno VARCHAR(25) NOT NULL,
bpno VARCHAR(25) NOT NULL,
saledate DATE NOT NULL,
total NUMERIC(19,4) NOT NULL DEFAULT 0,
CONSTRAINT pk_sale PRIMARY KEY (saleno),
CONSTRAINT fk_sale_rel_bp FOREIGN KEY (bpno) REFERENCES bp(bpno) ON UPDATE CASCADE ON DELETE RESTRICT
);

Saya membuat dua buah report melalui iReport,
report pertama berisi chart dengan query sebagai berikut

SELECT a.bpno, bp.bpname, a.total
FROM (
SELECT bpno, SUM(total) AS total FROM sale GROUP BY bpno ORDER BY SUM(total) DESC LIMIT 5
) a JOIN bp ON a.bpno=bp.bpno
ORDER BY total DESC

Kemudian saya mengeset hyperlink dari chart tersebut, klik kanan pada chart dan akses menu Chart Data
Chart Data

Selanjutnya pada dialog Chart details pilih tab Details -> Pie series -> Section hyperlink, ganti opsi Hyperlink target dengan opsi Self, sedangkan Hyperlink type dengan opsi RemoteAnchor.
Dan juga saya menambahkan dua link parameterBP_NO yang mereferensi pada field $F{bpno}, dan BP_NAME yang mereferensi pada field $F{bpname}.
Hyperlink
Sedangkan report kedua saya menggunakan query berikut ini
SELECT bpno, saledate, saleno, total FROM sale WHERE bpno=$P{BP_NO}

Seperti querynya, pada report ke-2 saya menambahkan dua parameter BP_NO dan BP_NAME, yang nantinya akan dihubungkan dengan link parameter pada report pertama.

Beralih ke sisi program, saya membuat aplikasi swing melalui Netbeans dengan Maven -> Java Application, bukan Java -> Java Application. Saya pilih maven untuk kemudahan mensetting library/dependency.

Karena saya akan menggunakan JasperViewer untuk menampilkan report dan JasperViewer tidak memiliki method untuk mengakses JRViewer yang memiliki modifier protected (agar bisa menambahkan listener), maka saya membuat class ReportViewer yang meng-extends class JasperViewer dan menambahkan method getJRViewer.

public JRViewer getJRViewer() {
        return viewer;
}

Selanjutnya pada class FrmChartSale (form laporan, saya menggunakan JInternalFrame), saya meng-implements JRHyperlinkListener
public class FrmChartSale extends ReportIFrame implements JRHyperlinkListener {

    @Override
    public void gotoHyperlink(JRPrintHyperlink hyperlink) throws JRException {
        parameterMap = new HashMap();
        List<JRPrintHyperlinkParameter> parameters = hyperlink.getHyperlinkParameters().getParameters();

        for (JRPrintHyperlinkParameter parameter : parameters) {
            parameterMap.put(parameter.getName(), parameter.getValue());
        }

        hyperlinkMode = true;
        viewReport(this.getTitle() + " | Daftar Penjualan");
    }
}

dan jangan lupa untuk menambahkan listenernya ke JRViewer

@Override
public void registerHyperlinkListener() {
    jasperViewer.getJRViewer().addHyperlinkListener(this);
}

Dan voila, program berjalan dengan baik, ketika chart pada report pertama saya klik, maka report ke-2 akan tampil.

Source codenya bisa diakses melalui repository github saya di https://github.com/ekosuhariyadi.

Happy coding :)

Comments

Popular posts from this blog

Java | Menambahkan Dialog Konfirmasi Sebelum Keluar dari Aplikasi

Kali ini saya ingin berbagi cara sederhana untuk menampilkan dialog konfirmasi sebelum keluar dari aplikasi. Dengan syarat aplikasi yang kita buat harus menggunakan JFrame sebagai frame utama. Langkah-langkah yang harus kita lakukan adalah sebagai berikut: 1. Ganti property default close operation dari JFrame menjadi DO_NOTHING_ON_CLOSE, value ini dimaksudkan agar ketika button close dari JFrame diklik tidak akan terjadi apa-apa. Sebaliknya jika valuenya adalah EXIT_ON_CLOSE, maka ketika button close dari JFrame diklik maka program akan tertutup. setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); 2. Yang kedua adalah kita harus menambahkan WindowListener pada JFrame. Interface WindowListener memiliki beberapa method terkait event terhadap window (yakni JFrame), namun yang harus kita override hanyalah method windowClosing, method ini akan dipanggil ketika button close diklik.   Sebagai informasi, apabila kita menambahkan WindowListener secara langsung maka semua method dari i

PostgreSQL | Membuat Nomor Urut dengan Window Function ROW_NUMBER()

Pengguna Oracle Database mungkin sudah sangat familiar dengan clausa ROWNUM. Bagi yang belum tahu apa itu ROWNUM,  ROWNUM  adalah  pseudo column  (kolom bayangan) yang berisi nomor urut dari hasil eksekusi query. Sayangnya fitur ini belum tersedia pada PostgreSQL . Namun ada kabar gembira bagi kita pengguna  PostgreSQL , dimana sejak versi 8.4, PostgreSQL telah menyediakan 1 window function  yang mengakomodasi masalah ROWNUM, yakni ROW_NUMBER() . Sesuai dengan dokumentasi yang disediakan, cara menggunakan fungsi ini adalah dengan menggabungkannya dengan clausa OVER  yang didalamnya berisi clausa ORDER BY . Supaya lebih jelas dan lebih mudah dipahami, lebih baik langsung kita praktekkan saja. Saya membuat sebuah table dengan struktur sebagai berikut CREATE TABLE name ( code CHAR(1) ); yang kemudian saya isi kolom code dengan alfabet mulai dari a s/d z  dan angka 0 (nol). Sebelumnya kita lakukan query ke table name tanpa clausa ORDER BY : SELECT code FROM name; Outputny

PostgreSQL | Ekspresi Kondisional CASE Pada Query

Salah satu fitur yang saya sukai dari PostgreSQL adalah dapat digunakannya ekspresi kondisional pada query. PostgreSQL menyediakan ekpresi CASE yang memiliki fungsi yang sama dengan statemen IF/ELSE pada bahasa pemrograman. Berikut adalah bentuk dari ekspresi CASE pada PostgreSQL CASE WHEN condition THEN result      [WHEN ...]      [ELSE result] END Untuk melihat bagaimana cara menggunakan ekspresi CASE, saya memiliki sebuah tabel number dengan sebuah kolom nomor yang memuat data bertipe integer. SELECT nomor FROM number ORDER BY nomor;  nomor -------      1      3     32     37     38     97 (6 rows) Sekarang mari kita gunakan ekspresi CASE untuk menentukan apakah nomor tersebut merupakan bilangan ganjil atau genap. SELECT nomor, (CASE WHEN nomor % 2 = 0 THEN 'Bilangan Genap' ELSE 'Bilangan Ganjil' END) AS status FROM number ORDER BY nomor; dan hasilnya adalah sebagai berikut:  nomor |     status     -------+-----------------      1 | Bilangan