Format Baris Teks untuk dokumen menggunakan Java

Banyak library Java yang memberikan kemudahan untuk menciptakan dokumen dalam format Excel, PDF, dan format modern (dan canggih) lainnya. Namun bagaimana jika yang dibutuhkan hanya untuk membuat dokumen teks sederhana saja, namun membutuhkan pengaturan baris sederhana, misalnya kolom, dan rata kiri-kanan-tengah.

Kasus yang umum terjadi misalnya, ketika membuat dokumen yang akan dicetak dengan menggunakan printer Dot Matrix, misalnya membuat nota penjualan. Meskipun, tentu saja, bisa juga mencetak PDF langsung di printer tersebut, namun umumnya akan memakan waktu lebih lama dan hasilnya mungkin tidak sebagus jika mencetak file *.txt saja.

Misalnya, ingin membuat dokumen teks seperti berikut

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
            Toko Terang Gelap           
         Jln. Lampu Senter No 33        
               Kota Senja               
========================================
Nota No. 778899      29/10/2015 11:23:55
----------------------------------------
 Qty        Nama Barang          Total  
----------------------------------------
  1  Item 1                           10
  2  Item 2                          200
  3  Item 3                         3000
  4  Item 4                        40000
  5  Item 5                       500000
----------------------------------------
              Terima Kasih              
           Atas Kunjungan Anda          
========================================

Perhatikan bahwa dokumen tersebut hanya berupa teks saja, tanpa format yang Rich. Format yang ada hanyalah rata kiri, kanan, dan tengah. Namun format tersebut dapat pula diaplikasikan di dalam 1 baris, dengan kolom-kolom seperti tabel.

Format rata kiri, kanan, tengah tersebut sebenarnya hanya dihasilkan dengan jumlah spasi yang tepat agar dalam 1 baris, teks yang diinginkan dapat diletakkan di bagian yang sesuai.

Kembali ke topik tentang penggunaan Java untuk membuat dokumen seperti ini. Dokumen diatas dihasilkan dengan script Java berikut ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public static void main(String[] args){
 
        LineFormatter lf = new LineFormatter(40);
 
        lf.addLine("Toko Terang Gelap", LineFormatter.CENTER_ALIGN);
        lf.addLine("Jln. Lampu Senter No 33", LineFormatter.CENTER_ALIGN);
        lf.addLine("Kota Senja", LineFormatter.CENTER_ALIGN);
        lf.addDivider("=");
        lf.addLine(
                new LineColumn("Nota No. 778899", 20)
                        .addColumn("29/10/2015 11:23:55", 20, LineFormatter.RIGHT_ALIGN)
        );
        lf.addDivider("-");
 
        lf.addLine(
                new LineColumn("Qty", 5, LineFormatter.CENTER_ALIGN)
                        .addColumn("Nama Barang", 25, LineFormatter.CENTER_ALIGN)
                        .addColumn("Total", 10, LineFormatter.CENTER_ALIGN)
        );
        lf.addDivider("-");
 
        for(int i = 1; i <= 5; i++){
            lf.addLine(
                    new LineColumn(i + " ", 5, LineFormatter.CENTER_ALIGN)
                            .addColumn("Item " + i, 25)
                            .addColumn("" + (i * ((int)Math.pow(10, i))), 10, LineFormatter.RIGHT_ALIGN)
            );
        }
 
        lf.addDivider("-");
        lf.addLine("Terima Kasih", LineFormatter.CENTER_ALIGN);
        lf.addLine("Atas Kunjungan Anda", LineFormatter.CENTER_ALIGN);
        lf.addDivider("=");
 
        System.out.println( lf.render() );
}

Disini, yang saya gunakan adalah class LineFormatter dan LineColumn.

LineFormatter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package gaisma.components.plaintext;
 
import gaisma.Params;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * Created with IntelliJ IDEA.
 * User: lee
 * Date: 11/29/13
 * Time: 9:28 PM
 * <p/>
 * Java Plain Text Line Formatter
 */
public class LineFormatter {
    public static final int LEFT_ALIGN = -1;
    public static final int CENTER_ALIGN = 0;
    public static final int RIGHT_ALIGN = 1;
 
    private int lineWidth;
    private List<String> lines;
    private String newLine = System.getProperty("line.separator");
 
    public static String LEFT_MARGIN = ""; // nothing
 
    /**
     * Initialize LineFormatter with line width initialized as 40 (epson POS printer)
     */
    public LineFormatter() {
        init(40);
    }
 
    /**
     * Initialize LineFormatter with specified line width
     *
     * @param l : line width
     */
    public LineFormatter(int l) {
        init(l);
    }
 
    /**
     * Set new line character, this is not necessary as LineFormatter automatically detect System new line character
     *
     * @param n : new line character
     * @return current LineFormatter instance
     */
    public LineFormatter setNewLine(String n) {
        this.newLine = n;
        return this;
    }
 
    private void init(int l) {
        this.lineWidth = l;
        lines = new ArrayList<String>();
    }
 
    /**
     * add new line
     *
     * @param cols LineColumn Class instance from whose columns constructed as line
     * @return current LineFormatter instance
     */
    public LineFormatter addLine(LineColumn cols) {
        return addLine(cols.getLine());
    }
 
    /**
     * add new line, with LineFormatter.LEFT_ALIGN
     *
     * @param s line to be added
     * @return current LineFormatter instance
     */
    public LineFormatter addLine(String s) {
        return addLine(s, LEFT_ALIGN);
    }
 
    /**
     * add new line, with specified alignment
     *
     * @param s     line to be added
     * @param align
     * @return current LineFormatter instance
     */
    public LineFormatter addLine(String s, int align) {
        switch (align) {
            case LEFT_ALIGN:
                return saveLine(String.format("%-" + this.lineWidth + "s", s));
            case RIGHT_ALIGN:
                return saveLine(String.format("%" + this.lineWidth + "s", s));
            case CENTER_ALIGN:
                int sw = s.length();
                int pad = (this.lineWidth - sw) / 2;
                String l = String.format("%" + pad + "s%s%" + pad + "s", "", s, "");
                return addLine(l, RIGHT_ALIGN);
        }
        return null;
    }
 
    private LineFormatter saveLine(String s) {
        if (s.length() > this.lineWidth)
            s = s.substring(0, this.lineWidth);
        this.lines.add(LEFT_MARGIN + s);
        return this;
    }
 
    /**
     * add blank line
     *
     * @return current LineFormatter instance
     */
    public LineFormatter addDivider() {
        return addLine(" ");
    }
 
    /**
     * add line with repeated character
     *
     * @param s single string to be repeated
     * @return current LineFormatter instance
     */
    public LineFormatter addDivider(String s) {
        return addLine(
                String.format("%" + lineWidth + "s", s)
                        .replace(' ', s.charAt(0))
        );
    }
 
    /**
     * produce formatted lines
     *
     * @return rendered string
     */
    public String render() {
        String text = "";
        if (lines.size() > 0) {
            text = lines.get(0);
        }
        for (int i = 1; i < lines.size(); i++) {
            text += this.newLine + lines.get(i);
        }
 
        return text;
    }
 
    /**
     * clear all buffered line
     *
     * @return current LineFormatter instance
     */
    public LineFormatter reset() {
        lines.clear();
        return this;
    }
}

LineColumn.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package gaisma.components.plaintext;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * Created with IntelliJ IDEA.
 * User: lee
 * Date: 11/29/13
 * Time: 9:39 PM
 */
public class LineColumn {
 
    private List<String> columns = new ArrayList<String>();
    public LineColumn(){
 
    }
 
    public LineColumn(String s, int width){
        this.addColumn(s, width);
    }
 
    public LineColumn addBlankSpace(int width){
        return this.addColumn(" ", width);
    }
 
    public LineColumn(String s, int width, int align){
        addColumn(s, width, align);
    }
 
    public LineColumn addColumn(String s, int width){
        return addColumn(s, width, LineFormatter.LEFT_ALIGN);
    }
 
    public LineColumn addColumn(String s, int width, int align){
        if(s.length() > width)
            s = s.substring(0, width);
 
        switch (align){
            case LineFormatter.LEFT_ALIGN:
                columns.add(String.format("%-" + width + "s", s));
            break;
            case LineFormatter.RIGHT_ALIGN:
                columns.add(String.format("%" + width + "s", s));
            break;
            case LineFormatter.CENTER_ALIGN:
                int sw = s.length();
                int pad = (width - sw) / 2;
                String l = String.format("%" + pad + "s%s%" + pad + "s", "", s, "");
                return addColumn(l, width, LineFormatter.RIGHT_ALIGN);
        }
 
        return this;
    }
 
    public String getLine(){
        String line = "";
        for(int i = 0; i < columns.size(); i++){
            line += columns.get(i);
        }
 
        return line;
    }
}

LineFormatter adalah class utama yang akan membuat format teks dapat diatur agar ditempatkan dalam format rata kiri, kanan, atau tengah. Sedangkan LineColumn, berguna agar dalam 1 baris, dapat dibuat beberapa kolom, yang masing-masing kolom dapat diberikan format sendiri sendiri.

Dua class ini saya buat karena punya kebutuhan membuat dokumen teks sederhana, dan aplikasinya sendiri diusahakan agar dapat berukuran sekecil-kecilnya. Pencarian singkat di Google tidak membuahkan hasil library yang sesuai, dan alasan itulah yang membuat saya menciptakan library ini.

Atau mungkin Anda tahu Library yang lain? Comment ya.
Terima kasih, semoga bisa berguna untuk kita semua.