Mencetak Ke Printer Dot-Matrix Di Java Dengan simple-escp


Salah satu teknologi lama yang masih bertahan sampai saat ini adalah printer dot matrix. Salah satu alasan utama
penggunaan printer tersebut adalah untuk mencetak pada kertas karbon yang secara otomatis membuat duplikasi ke beberapa halaman berbeda. Berdasarkan data dari Wikipedia, hingga tahun 2013, hanya ada 1 perusahaan di Canada, 1 perusahaan di United Kingdom, dan 2 perusahaan di Amerika yang masih memproduksi kertas karbon. Di India (dan juga Indonesia), penggunaan kertas karbon untuk mengisi formulir masih sering dijumpai. Teknologi kertas karbon sebenarnya sudah kalah bersaing menghadapi mesin fotokopi (photocopying), printer laser yang semakin murah dan penggunaan formulir elektronik.

Printer dot matrix mencetak karakter berdasarkan font internal (dalam RAM printer) dan bekerja dengan sangat baik di DOS. Hal ini karana karakter ganti baris di DOS yang berupa 2 karakter, CR + LF, sehingga file DOS dapat langsung dicetak ke printer (saat itu belum ada driver terpisah untuk masing-masing printer). Tradisi ini juga dibawa ke sistem operasi Windows (bandingkan dengan Linux dan Unix yang hanya memakai karakter LF untuk ganti baris).

Seiring dengan perkembangan printer inkjet yang dapat mencetak piksel secara fleksibel dan lebih sunyi, sistem operasi modern mulai beralih mendukung mereka. Printer inkjet memiliki bahasa percetakan yang lebih mudah distandarisasikan. Sebagai contoh, sistem operasi bisa memakai font di sisi software yang berlaku untuk semua printer (di Windows, ini bisa dijumpai di folder C:\Windows\Fonts). Dukungan software pun beralih meninggalkan dot matrix dengan asumsi bahwa teknologi dot matrix akan mati dengan sendirinya.

Sampai sekarang, masih ada produsen yang tetap memproduksi printer dot matrix dan memasarkannya dengan harga yang mahal (akibat monopoli). Lalu apakah printer dot matrix tersebut dapat dipakai pada sistem operasi modern? Yup! Bisa! Mereka dilengkapi dengan driver yang akan menerjemahkan gambar dan dokumen untuk dicetak pada modus grafis oleh printer sehingga dapat bekerja pada software modern seperti Microsoft Office. Percetakan graphic mode bukanlah percetakan text mode (atau raw mode) yang mencetak karakter per karakter. Percetakan graphic mode lebih lambat dan pengaturan posisi karakter lebih sulit dilakukan dibandingkan pada text mode.

Salah satu solusi untuk mendapatkan posisi percetakan yang rapi di graphic mode adalah memakai font bawaan printer. Microsoft Word, misalnya, akan menampilkan font bawaan printer bila printer dot matrix dipilih sebagai default printer. Mengubah printer dot matrix tersebut menjadi default printer adalah sesuatu yang wajib karena font disimpan di dalam RAM printer (disebut sebagai printer device font), bukan di C:\Windows\Fonts.

Lalu, apakah saya dapat menggunakan printer device font di iReport atau JasperReport? Sayang sekali, jawabannya tidak! Java dirancang untuk tidak terikat pada satu platform tertentu. Memakai printer device font bukan hanya terikat pada sistem operasi, tapi juga terikat pada ketersediaan sebuah hardware printer merk tertentu. Pada komputer yang tidak memiliki printer ini, tampilan bisa jadi berantakan. Dengan demikian, saya tidak dapat memakai JasperReport untuk menghasilkan laporan text mode yang memiliki posisi dan ukuran yang bisa saya kendalikan secara mudah.

Walaupun demikian, saya masih dapat memakai Java Print Service (JPS) untuk mencetak text mode di Java. Hanya saja, tanpa kemampuan templating seperti di JasperReport, ini akan menjadi sebuah tantangan tersendiri. Untuk mengatasi masalah ini, saya akan menggunakan simple-escp yang menyediakan fasilitas templating dan preview khusus untuk text mode. simple-escp juga menyediakan cara mudah untuk memberikan perintah ESC/P (Epson Standard Code for Printers) untuk melakukan pengaturan pada printer. Dokumentasi untuk simple-escp dapat dibaca di http://jockihendry.github.io/simple-escp/. Pada artikel ini, saya akan mencoba membuat sebuah program Java sederhana yang mencetak ke printer dot-matrix dengan menggunakan simple-escp.

Langkah pertama yang saya lakukan adalah men-download file JAR simple-escp di lokasi https://github.com/JockiHendry/simple-escp/releases. Berikutnya, saya akan membuat proyek baru di IntelliJ IDEA dengan memilih menu File, New Project. Pada dialog yang muncul, saya memilih Java dan men-klik tombol Next dua kali, mengisi nama proyek dan men-klik tombol Finish.

Saya kemudian men-klik kanan nama proyek dan memilih menu Open Module Settings. Pada dialog yang muncul, saya men-klik tombol tambah, lalu memilih Jar or Directories… untuk menambahkan JAR milik simple-escp sehingga dialog terlihat seperti pada gambar berikut ini:

Menambah library simple-escp

Menambah library simple-escp

Saya kemudian men-klik tombol Ok dua kali.

Berikutnya, saya akan membuat sebuah kode program yang akan melakukan percetakan. Untuk itu, saya men-klik kanan folder src dan memilih menu New, Java Class. Saya memberi nama Main pada class tersebut dan mengisinya seperti pada kode program berikut ini:

import simple.escp.SimpleEscp;
import simple.escp.util.EscpUtil;

public class Main {

    public static void main(String[] args) {
        SimpleEscp simpleEscp = new SimpleEscp("EPSON LX-310 ESC/P");
        simpleEscp.print(EscpUtil.escSelectUnderline() +
            "Ini akan digarisbawahi" + EscpUtil.escCancelUnderline());
    }

}

Setelah itu, saya men-klik bagian yang kosong pada kode program class tersebut dan memilih menu Run Main.main().

Begitu program dijalankan, ia akan langsung mencetak ke printer yang bernama EPSON LX-310 ESC/P. Tulisan yang dicetak akan memiliki garis bawah. Untuk melihat daftar nama printer di Windows, klik Start Menu di pojok kiri bawah layar dan pilih Devices and Printers.

Biasanya akan ada 1 printer yang dianggap sebagai default printer yang menjadi target percetakan. Bila seandainya printer dot matrix yang ingin saya pakai sudah di-set sebagai default printer di sistem operasi, maka saya dapat mengganti perintah new SimpleEscp("NAMA_PRINTER") menjadi new SimpleEscp(). Membuat instance SimpleEscp tanpa parameter akan secara otomatis memakai default printer.

Rasanya tidak cukup bila hanya bisa mencetak dan memberikan perintah ESC/P saja. Kebutuhan percetakan bisa saja lebih kompleks dari ini. Beruntungnya, simple-escp menyediakan fasilitas template dalam bentuk JSON. Untuk membuat template JSON, saya men-klik kanan folder src dan memilih menu New, File. Saya kemudian memberi nama file berupa template.json dan men-klik tombol Ok.

Saya mengisi file template.json menjadi seperti berikut ini:

{
     "pageFormat": {
         "pageLength": 10,
         "pageWidth": 50,
         "usePageLengthFromPrinter": false
     },
     "template": {                    
         "header": [ "  PT. XYZ                              HAL: %{PAGE_NO}" ],
         "detail": [ 
             " Ini adalah baris %{LINE_NO} dari halaman %{PAGE_NO} ",
             " ini adalah baris %{LINE_NO} dari halaman %{PAGE_NO} "
         ]
     }
 }

File JSON di simple-escp terdiri atas 2 bagian, pageFormat dan template. Pada pageFormat, saya dapat menentukan pengaturan seperti ukuran halaman (panjang dalam baris dan lebar dalam jumlah karakter). Pada contoh di atas, saya juga memberi nilai usePageLengthFromPrinter dengan false agar ukuran halaman yang tersimpan di RAM printer diabaikan dan ukuran efektif yang berlaku adalah yang telah saya tentukan (10 baris x 50 karakter). Ini akan mempengaruhi posisi akhir ketika menekan tombol Tear Off di printer.

Pada bagian template, saya dapat memakai key berupa firstPage, header, detail, footer, dan lastPage. Pada template di atas, saya hanya mendeklarasikan section header dan detail. Isi dari header akan selalu dicetak di setiap awal halaman.

simple-escp mendukung function dalam syntax seperti %{...}. Pada contoh di atas, %{PAGE_NO} akan diganti menjadi nomor halaman (mulai dari 1) dan %{LINE_NO} akan diganti menjadi nomor baris (mulai dari 1).

Untuk mencetak JSON template di atas, saya dapat membuat kode program seperti berikut ini:

import simple.escp.SimpleEscp;
import simple.escp.Template;
import simple.escp.fill.FillJob;
import simple.escp.json.JsonTemplate;
import simple.escp.util.EscpUtil;

public class Main {

    public static void main(String[] args) {
        try {
            SimpleEscp simpleEscp = new SimpleEscp("EPSON LX-310 ESC/P");
            Template template = new JsonTemplate(Main.class.getResourceAsStream("template.json"));
            String hasil = new FillJob(template.parse()).fill();
            simpleEscp.print(hasil);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}

Pada kode program di atas, saya memakai FillJob untuk menerjemahkan JsonTemplate menjadi sebuah String biasa. Setelah itu, saya mencetak String tersebut dengan simpleEscp.print().

Selain function, simple-escp juga mendukung placeholder dalam syntax seperti ${...}. Placeholder dapat dianggap seperti variabel yang akan diganti nilainya berdasarkan sumber data yang dipakai. Sumber data yang dipakai oleh simple-escp ditangani oleh salah satu implementasi interface DataSource. Saat ini, simple-escp dilengkapi dengan BeanDataSource untuk membaca nilai dari sebuah object dan MapDataSource untuk membaca nilai dari sebuah Map.

Sebagai latihan, saya akan mengubah isi file template.json agar memakai placeholder:

{
     "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": 15, "wrap": true },
                    { "caption": "Qty", "source": "qty::right", "width": 10 },
                    { "caption": "Harga", "source": "harga::right", "width": 20 }
                ]
             }
         ]
     }
 }

Placeholder seperti ${nomorFaktur:20} akan diganti dengan nilai nomorFaktur dari DataSource. Bila nilai
tersebut melebihi batas 20 karakter, maka isinya akan dipotong sehingga nilai dari placeholder tidak akan pernah
lebih dari 20 karakter. Bila kurang dari 20 karakter, maka sisa ruang sisa akan di-isi dengan spasi.

Pada template di atas, saya juga membuat sebuah table yang terdiri atas 3 kolom. Isi dari tabel tersebut akan diambil dari nilai listItemFaktur di DataSource. Nilai dari listItemFaktur wajib harus berupa Collection, misalnya sebuah List. Penggunaan "wrap": true pada kolom akan menyebabkan nilai yang melebihi batas kolom tidak dipotong, melainkan dicetak pada baris berikutnya. Nilai "source" seperti "qty::right" akan menyebabkan nilai dicetak dengan rata kanan.

Berikutnya, karena saya ingin sumber data laporan diambil dari objek, maka saya membuat class Faktur yang isinya seperti berikut ini:

import java.util.ArrayList;
import java.util.List;

public class Faktur {

    private String nomorFaktur;
    private List<ItemFaktur> listItemFaktur = new ArrayList<ItemFaktur>();

    public Faktur(String nomorFaktur) {
        this.nomorFaktur = nomorFaktur;
    }

    public String getNomorFaktur() {
        return nomorFaktur;
    }

    public List<ItemFaktur> getListItemFaktur() {
        return listItemFaktur;
    }

    public void tambahItemFaktur(ItemFaktur itemFaktur) {
        this.listItemFaktur.add(itemFaktur);
    }
}

Class tersebut akan membutuhkan class ItemFaktur yang isinya seperti berikut ini:

import java.math.BigDecimal;

public class ItemFaktur {

    private String namaBarang;
    private Integer qty;
    private BigDecimal harga;

    public ItemFaktur(String namaBarang, Integer qty, BigDecimal harga) {
        this.namaBarang = namaBarang;
        this.qty = qty;
        this.harga = harga;
    }

    public String getNamaBarang() {
        return namaBarang;
    }

    public Integer getQty() {
        return qty;
    }

    public BigDecimal getHarga() {
        return harga;
    }

}

Sekarang, saya dapat mendeklarasikan sebuah objek yang menjadi sumber data seperti berikut ini:

Faktur faktur = new Faktur("FA-1234-556677-XX-BB-CC");
faktur.tambahItemFaktur(new ItemFaktur("Plantronics Backbeat Go 2 With Charging Case",
    1, new BigDecimal("13750000")));
faktur.tambahItemFaktur(new ItemFaktur("CORT Gitar Akustik AD810 - Natural Satin",
    1, new BigDecimal("14900000")));
faktur.tambahItemFaktur(new ItemFaktur("SAMSON Monitor Speaker System MediaOne 3A",
    1, new BigDecimal("14250000")));

Untuk menghasilkan String dan mencetak laporan, saya dapat menggunakan cara singkat seperti berikut ini:

SimpleEscp simpleEscp = new SimpleEscp("EPSON LX-310 ESC/P");            
Template template = new JsonTemplate(Main.class.getResourceAsStream("template.json"));            
simpleEscp.print(template, DataSources.from(faktur));

Factory DataSources akan menghasilkan class DataSource secara otomatis (dalam hal ini adalah BeanDataSource). Bila kode program di atas dijalankan, maka printer akan langsung mencetak tabel sesuai dengan isi dari objek faktur.

Ada kalanya lebih baik memberikan tampilan preview bagi pengguna sebelum mencetak. Untuk kebutuhan ini, simple-escp dilengkapi dengan komponen PrintPreviewPane yang merupakan sebuah JPanel untuk menampilkan preview percetakan. Sebagai latihan, untuk memakai PrintPreviewPane, saya mengubah kode program menjadi berikut ini:

import simple.escp.Template;
import simple.escp.json.JsonTemplate;
import simple.escp.swing.PrintPreviewPane;
import javax.swing.*;
import java.awt.*;
import java.math.BigDecimal;

public class Main extends JFrame {

    public Main() {
        super("Latihan");

        Faktur faktur = new Faktur("FA-1234-556677-XX-BB-CC");
        faktur.tambahItemFaktur(new ItemFaktur("Plantronics Backbeat Go 2 With Charging Case",
                1, new BigDecimal("13750000")));
        faktur.tambahItemFaktur(new ItemFaktur("CORT Gitar Akustik AD810 - Natural Satin",
                1, new BigDecimal("14900000")));
        faktur.tambahItemFaktur(new ItemFaktur("SAMSON Monitor Speaker System MediaOne 3A",
                1, new BigDecimal("14250000")));

        Template template  = null;
        try {
            template = new JsonTemplate(Main.class.getResourceAsStream("template.json"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        PrintPreviewPane preview = new PrintPreviewPane(template, null, faktur);
        setLayout(new BorderLayout());
        add(preview, BorderLayout.CENTER);

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Main();
    }

}

Bila program dijalankan, akan muncul tampilan seperti pada gambar berikut ini:

Tampilan PrintPreviewPanel

Tampilan PrintPreviewPanel

Pengguna kini dapat menentukan sendiri kapan memulai percetakan dengan men-klik tombol Print pada PrintPreviewPane.

Perihal Solid Snake
I'm nothing...

6 Responses to Mencetak Ke Printer Dot-Matrix Di Java Dengan simple-escp

  1. masturfyc mengatakan:

    artikel bagus, terima kasih. saya baru memulai pemrograman dengan java, dan saya butuh cara mencetak ke printer matrik. sebelumnya saya menggunakan c#.net

  2. dhani isMoyo p (Moy) mengatakan:

    Bagaimana jika saya ingin mencetak menggunakan print yang ada di PC lain dalam satu jaringan/LAN? Printer sudah disharing, apa yang harus saya lakukan?

  3. agus gus mengatakan:

    master gimana caranya kalo cetak datanya dari database mohon bantuanya..

  4. agus gus mengatakan:

    terus juga kalo input datanya kita input dari textfield gimana caranya…

  5. Rizal Yugo Prasetyo mengatakan:

    bagaimana menggunakan plugin ini di netbeans?

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: