Memakai simple-escp Pada Aplikasi Web


Pengguna bisa mencetak melalui browser dengan memilih menu File, Print.. di browser atau melalui JavaScript window.print(). Percetakan yang dilakukan dengan cara seperti ini adalah percetakan graphic mode. Bagaimana bila yang diinginkan adalah percetakan text mode? Pada percetakan text mode, posisi bisa ditentukan secara lebih akurat dan pengaturan halaman dapat dilakukan dalam satuan baris dan karakter. simple-escp adalah salah satu library Java yang dapat dipakai untuk keperluan ini. Untuk memakai simple-escp pada aplikasi web, saya dapat menyertakannya sebagai applet. Applet adalah kode program Java yang akan dikerjakan di sisi client di browser (sama seperti Adobe Flash, Microsoft Silverlight, ActiveX, dan sebagainya). Salah satu fitur andalan applet adalah kode program JavaScript di halaman HTML yang sama dapat dipakai untuk memanipulasi applet. Begitu juga sebaliknya, applet juga dapat memanggil kode program JavaScript yang dideklarasikan pada halaman HTML yang sama.

Untuk membuat applet, saya dapat menggunakan framework Griffon. Saya akan mulai dengan membuat proyek baru dengan memberikan perintah:

griffon create-app simple-escp-applet

Karena applet ini akan memanggil simple-escp, saya perlu mengubah bagian griffon.project.dependency.resolution dari griffon-app/conf/BuildConfig.groovy menjadi seperti berikut ini:

griffon.project.dependency.resolution = {
    // inherit Griffon' default dependencies
    inherits("global") {
    }
    log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
    repositories {
        griffonHome()
        mavenRepo "http://dl.bintray.com/jockihendry/maven"
    }
    dependencies {
        compile 'jockihendry:simple-escp:0.4'
    }
}

Saya juga perlu mengubah bagian webstart agar nilai codebase merujuk ke lokasi URL di server nanti, seperti pada contoh berikut ini:

production {
    ...
    griffon {
       ...
       webstart {
          codebase = "http://localhost/cetak"
       }
    }
}

Selain itu, saya akan memanggil JavaScript yang ada di HTML melalui Applet melalui netscape.javascript.JSObject. Class ini terletak pada plugin.jar dan tidak tersedia pada saat kompilasi. Untuk itu, saya men-copy file tersebut dari C:\Program Files\Java\jdk\jre\lib ke folder lib di proyek Griffon.

Karena saya perlu melakukan signing pada applet yang dihasilkan Griffon, maka saya mengubah bagian signingkey di environment production menjadi seperti berikut ini:

production {
   signingkey {
      params {                
         storepass = 'thesolidsnake'
         keypass = 'thesolidsnake'
         lazy = false // sign, regardless of existing signatures
      }
   }
   ...
}

Sekarang, saya siap untuk membuat kode program. Satu hal yang menjadi kendala adalah DataSource. Saat ini simple-escp menerima DataSource dalam bentuk Map atau JavaBean object yang merupakan tipe data Java. Kedua data source tersebut tidak dapat dipakai di JavaScript. Untuk itu, saya perlu membuat DataSource baru yang bisa membaca data dalam bentuk object JavaScript di halaman HTML yang sama. simple-escp memungkinkan pengguna membuat implementasi DataSource sendiri seperti yang terlihat pada kode program berikut ini (saya meletakkannya di src\main\datasource\JSONDataSource.groovy):

package datasource;

import simple.escp.data.DataSource;
import simple.escp.exception.InvalidPlaceholder;
import javax.json.Json;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
import java.io.StringReader;

public class JSONDataSource implements DataSource {

    private String jsonString;
    private JsonObject json;

    public JSONDataSource(String jsonString) {
        this.jsonString = jsonString;
        try (JsonReader reader = Json.createReader(new StringReader(jsonString))) {
            json = reader.readObject();
        }
    }

    @Override
    public boolean has(String s) {
        return json.containsKey(s);
    }

    @Override
    public Object get(String member) throws InvalidPlaceholder {
        JsonValue value = json.get(member);
        if (value.getValueType() == JsonValue.ValueType.ARRAY) {
            return value;
        } else if (value.getValueType() == JsonValue.ValueType.NUMBER) {
            return ((JsonNumber) value).bigDecimalValue();
        } else {
            return value.toString();
        }
    }

    @Override
    public Object getSource() {
        return jsonString;
    }

    @Override
    public String[] getMembers() {
        return json.keySet().toArray(new String[0]);
    }
}

Saya kemudian mengubah isi dari SimpleEscpAppletView.groovy menjadi seperti berikut ini:

package simple.escp.applet

import java.awt.BorderLayout

application() {

    panel(id: 'mainPanel', layout: new BorderLayout()) {

    }

}

Sebagai langkah terakhir dalam membuat applet, saya mengubah kode program SimpleEscpAppletController.groovy menjadi seperti berikut ini:

package simple.escp.applet

import datasource.JSONDataSource
import simple.escp.fill.FillJob
import simple.escp.json.JsonTemplate
import simple.escp.swing.PrintPreviewPane
import sun.plugin.javascript.JSObject
import javax.swing.JPanel
import java.awt.BorderLayout

class SimpleEscpAppletController {

    def model
    def view

    void mvcGroupInit(Map args) {
        def window = JSObject.getWindow(app)
        def report = new JsonTemplate(window.eval("JSON.stringify(template);")).parse()
        def dataSource = window.eval("JSON.stringify(source);");
        def result = new FillJob(report, new JSONDataSource(dataSource)).fill()
        PrintPreviewPane pane = new PrintPreviewPane(result,
            report.pageFormat.pageLength, report.pageFormat.pageWidth)
        JPanel mainPanel = view.mainPanel
        mainPanel.add(pane, BorderLayout.CENTER)
    }

}

Untuk menghasilkan applet, saya memberikan perintah berikut ini:

griffon package applet

Griffon secara otomatis akan menghasilkan file distribusi applet pada folder dist/applet. Pada folder ini, selain file JAR, saya juga akan menemukan file applet.jnlp yang dapat dipakai untuk memanggil applet di HTML. Seluruh file JAR juga sudah di-sign dengan key yang di-generate untuk keperluan sementara. Saya juga dapat menemukan file applet.html yang berisi contoh pemanggilan applet.

Berikutnya, saya memindahkan seluruh file JAR (dan juga versi yang sudah di-compress dalam bentuk .jar.pack.gz), file gambar, file JNLP dan file HTML ke lokasi deployment di webserver. Sebagai contoh, karena saya memakai NGINX, saya akan memindahkan file tersebut ke folder html/cetak. Saya kemudian mengubah file applet.html menjadi seperti berikut ini:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Latihan Cetak</title>
    <script>
    var template = {
        pageFormat: {
            pageLength: 10,
            pageWidth: 50,
            usePageLengthFromPrinter: false
        },
        template: {
            header: [" PT. XYZ                                    HAL: %{PAGE_NO}"],
            detail: [
                " Nomor Faktur: ${nomorFaktur:20}",
                {
                    "table": "listItemFaktur",
                    "border": true,
                    "columns": [
                        { caption: "Nama Barang", source: "namaBarang", width: 25, wrap: true },
                        { caption: "Qty", source: "qty::right", width: 5 },
                        { caption: "Harga", source: "harga.bigDecimalValue()::right::number", width: 15 }
                    ]
                }
            ]
        }
    };

    var source = {
        nomorFaktur: 'FA-1234-556677-XX-BB-CC',
        listItemFaktur: [
            {namaBarang: 'Plantronics Backbet Go 2 With Charging Case', qty: 1, harga: 13750000},
            {namaBarang: 'CORT Gitar Akustik AD810 - Natural Satin', qty: 1, harga: 14900000},
            {namaBarang: 'SAMSON Monitor Speaker System MediaOne 3A', qty: 1, harga: 14250000}
        ]
    };

  </script>
</head>
<body>

<h1>Latihan Cetak</h1>

<p>Halaman ini akan memanggil applet yang mencetak ke printer dot matrix dengan bantuan JavaScript.</p>

<APPLET CODEBASE='http://localhost/cetak'
        CODE='griffon.swing.SwingApplet'
        ARCHIVE='griffon-swing-runtime-1.4.0.jar,griffon-rt-1.5.0.jar,groovy-all-2.2.1.jar,javax.json-1.0.4.jar,javax.json-api-1.0.jar,jcl-over-slf4j-1.7.5.jar,jul-to-slf4j-1.7.5.jar,log4j-1.2.17.jar,plugin.jar,simple-escp-0.4.jar,simple-escp-applet-0.1.jar,slf4j-api-1.7.5.jar,slf4j-log4j12-1.7.5.jar'
        WIDTH='800' HEIGHT='500'>
    <PARAM NAME="java_arguments" VALUE="-Djnlp.packEnabled=true">
    <PARAM NAME='jnlp_href' VALUE='http://localhost/cetak/applet.jnlp'>
    <PARAM NAME='dragggable' VALUE='true'>
    <PARAM NAME='image' VALUE='griffon.png'>
    <PARAM NAME='boxmessage' VALUE='Loading Simple-escp-applet'>
    <PARAM NAME='boxbgcolor' VALUE='#FFFFFF'>
    <PARAM NAME='boxfgcolor' VALUE='#000000'>
    <PARAM NAME='codebase_lookup' VALUE='false'>
</APPLET>

</body>
</html>

Pada HTML di atas, saya mendeklarasikan dua variabel JavaScript yang wajib ada, yaitu variabel template dan source. Kedua variabel ini akan dibaca oleh applet dan masing-masing diterjemahkan menjadi JsonTemplate dan JSONDataSource. Pada kasus yang lebih kompleks, ini variabel source biasanya akan dihasilkan oleh sisi server. Sebagai contoh, bila bahasa pemograman di sisi server adalah PHP, saya dapat menggunakan function json_encode() untuk menghasilkan object JavaScript dari array atau object PHP yang mengimplementasikan JsonSerializable.

Sekarang, saya akan mencoba membuka halaman http://localhost/cetak/applet.html melalui browser pada sistem operasi yang telah memiliki instalasi Java. Saya menemukan dialog peringatan seperti berikut ini:

Peringatan di browser pada saat menjalankan applet

Peringatan di browser pada saat menjalankan applet

Karena saya memang ingin mengaktifkan Java di browser, maka saya memilih Later. Setelah itu, akan kembali muncul pesan peringatan lainnya seperti pada gambar berikut ini:

Peringatan saat menjalankan applet yang tidak sertifikatnya tidak diverifikasi

Peringatan saat menjalankan applet yang tidak sertifikatnya tidak diverifikasi

Pesan peringatan ini muncul karena JAR saya di-sign sendiri tanpa verifikasi dari pihak terpercaya seperti Verisign, GoDaddy dan sejenisnya (yang memungut biaya verifikasi). Pesan keamanan ini diberikan karena applet yang di-sign oleh publisher tak dikenal memiliki akses yang lebih leluasa dibandingkan applet yang tidak di-sign sama sekali, misalnya baca/tulis file serta melakukan percetakan.

Saya memberi tanda centang pada I accept the risk and want to run this application. dan men-klik tombol Run. Tampilan browser saya akan terlihat seperti pada gambar berikut ini:

Tampilan di browser

Tampilan di browser

Bila saya men-klik tombol Print dari PrintPreviewPane milik simple-escp, maka percetakan akan dilakukan pada text mode ke printer dot matrix yang sedang terpilih.

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: