IMIN Go-Print
Dokumentasi lengkap untuk mengintegrasikan printer thermal IMIN dengan aplikasi web Anda. Pelajari COMMANDS object, cara membuat iframe, dan JavaScript untuk print.
window.print() tanpa konversi, lihat
GoPrint3 โ
rocket_launch Getting Started
Ikuti langkah-langkah berikut untuk mulai menggunakan IMIN Go-Print di aplikasi web Anda.
๐ฑ Persyaratan Sistem
Sebelum memulai development
๐ช Install IMIN Go-Print App
Aplikasi IMIN Go-Print harus diunduh dan diinstall terlebih dahulu dari IMIN AppStore yang tersedia di perangkat IMIN Anda.
โ ๏ธ Penting: IMIN AppStore hanya dapat diakses melalui perangkat IMIN resmi. Jika belum memiliki device IMIN, hubungi Sales IMIN atau email ke sales@imin.sg
-
Buat Iframe
Tambahkan iframe tersembunyi sebagai "print sink" untuk menerima dan memproses perintah print.
HTML<!-- Iframe tersembunyi untuk print --> <iframe id="printSink" class="iframe-sink" style="display:none;"></iframe> -
Susun Command Array
Gunakan COMMANDS object untuk menyusun perintah thermal printing dalam format array.
JavaScript// Helper function untuk wrap text function wrapCommandText(raw) { return `'${String(raw).replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n")}'`; } // Contoh: Tiket Antrian const currentCode = "A-057"; const currentDesk = "Loket A"; const date = new Date().toLocaleString("id-ID"); const commandParts = [ "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT", // Center alignment "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON", // Bold ON wrapCommandText("NOMOR ANTRIAN\n"), // Header text "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT", "COMMANDS.TEXT_FORMAT.TXT_4SQUARE", // Double size wrapCommandText(currentCode + "\n\n"), // Nomor antrian besar "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF", // Bold OFF "COMMANDS.TEXT_FORMAT.TXT_NORMAL", // Normal size wrapCommandText("Nomor : " + currentCode + "\n\n"), wrapCommandText("Loket: " + currentDesk + " Estimasi: 3 menit\n"), wrapCommandText("Tanggal: " + date + "\n"), wrapCommandText("Terima kasih, harap menunggu panggilan.\n\n\n") ]; -
Kirim ke Print
Function JavaScript untuk mengirim command ke iframe dan trigger print.
JavaScriptfunction sendToIframe(commandArray) { // Gabungkan command array menjadi string const commandText = commandArray.join("\n"); // Dapatkan iframe element const printSink = document.getElementById("printSink"); const doc = printSink.contentDocument || printSink.contentWindow.document; // Tulis command ke iframe doc.open("text/plain"); doc.write(commandText); doc.close(); // Focus iframe dan trigger print printSink.contentWindow.focus(); setTimeout(() => { try { printSink.contentWindow.print(); } catch (err) { console.error("Gagal print:", err); alert("Print gagal. Pastikan menggunakan browser Chromium/WebView."); } }, 120); } // Cara pakai const btnPrint = document.getElementById("btnPrint"); btnPrint.addEventListener("click", () => { sendToIframe(commandParts); }); -
Loop Print (v1.5.0) - Print Berulang
Cara mencetak dokumen yang sama sebanyak beberapa kali dengan validasi input dan delay otomatis. Fitur ini sangat berguna untuk mencetak tiket atau struk dalam jumlah banyak.
HTML<!-- Input untuk jumlah print --> <div style="margin: 20px 0;"> <label> <span class="material-symbols-outlined">repeat</span> Jumlah Print: <input id="printLoopCount" type="number" min="1" max="5" value="1" /> </label> </div> <button id="btnPrint">Demo Print</button>JavaScript// Event handler untuk tombol print dengan loop btnPrint.addEventListener("click", () => { // 1. Ambil nilai input jumlah print const loopCountInput = document.getElementById("printLoopCount"); let loopCount = parseInt(loopCountInput.value) || 1; // 2. Validasi input (min 1, max 5) if (loopCount < 1) { loopCount = 1; loopCountInput.value = 1; } else if (loopCount > 5) { // Alert jika melebihi batas maksimal alert("โ ๏ธ Maksimal jumlah print adalah 5!\n\nSilakan masukkan angka antara 1-5."); loopCountInput.value = 5; return; // Stop eksekusi } // 3. Ambil payload/command yang akan dicetak const payload = preparePrintPayload(); // Function yang menyiapkan command const commandText = payload.commandPartsText; // 4. Loop print sebanyak loopCount for (let i = 0; i < loopCount; i++) { // Gunakan setTimeout dengan delay untuk menghindari konflik setTimeout(() => { sendToIframe(commandText); }, i * 150); // Delay 150ms antar print } }); // Penjelasan: // - Delay 150ms mencegah konflik antar print job // - Setiap print diberi jeda waktu agar printer bisa proses dengan baik // - Max 5 untuk menghindari buffer overflow pada printerlightbulb๐ก Kenapa Pakai Delay?- Mencegah Konflik: Print job yang terlalu cepat bisa saling bentrok
- Stabilitas Printer: Memberi waktu printer untuk proses setiap job
- Avoid Buffer Overflow: Printer punya buffer terbatas, delay mencegah overflow
- Delay Optimal: 150-200ms adalah sweet spot untuk kebanyakan printer
JavaScript - Alternative (Promise Based)// Alternative: Menggunakan async/await untuk kontrol yang lebih baik async function printMultiple(commandText, count) { for (let i = 0; i < count; i++) { // Print satu per satu dengan await await new Promise(resolve => { sendToIframe(commandText); setTimeout(resolve, 200); // Wait 200ms sebelum print berikutnya }); } console.log(`โ Selesai print ${count}x`); } // Cara pakai btnPrint.addEventListener("click", async () => { const loopCount = parseInt(document.getElementById("printLoopCount").value) || 1; if (loopCount > 5) { alert("Maksimal 5!"); return; } const payload = preparePrintPayload(); await printMultiple(payload.commandPartsText, loopCount); }); -
Contoh Lengkap - Print dengan Loop dan Loading Indicator
Implementasi lengkap dengan loading state dan feedback ke user.
JavaScript - Production Ready// Function lengkap dengan loading dan error handling async function handlePrintWithLoop() { const loopCountInput = document.getElementById("printLoopCount"); const btnPrint = document.getElementById("btnPrint"); let loopCount = parseInt(loopCountInput.value) || 1; // Validasi if (loopCount < 1 || loopCount > 5) { alert("โ ๏ธ Jumlah print harus antara 1-5"); return; } try { // Disable button saat print btnPrint.disabled = true; btnPrint.textContent = "Printing..."; // Siapkan command const payload = preparePrintPayload(); const commandText = payload.commandPartsText; // Print dengan loop for (let i = 0; i < loopCount; i++) { // Update progress btnPrint.textContent = `Printing ${i + 1}/${loopCount}...`; // Print await new Promise((resolve, reject) => { try { sendToIframe(commandText); setTimeout(resolve, 200); } catch (err) { reject(err); } }); } // Success btnPrint.textContent = `โ Printed ${loopCount}x`; setTimeout(() => { btnPrint.textContent = "Demo Print"; btnPrint.disabled = false; }, 2000); } catch (error) { // Error handling console.error("Print error:", error); alert("โ Print gagal: " + error.message); btnPrint.textContent = "Demo Print"; btnPrint.disabled = false; } } // Event listener document.getElementById("btnPrint").addEventListener("click", handlePrintWithLoop);
Pastikan aplikasi web Anda berjalan di Android dengan WebView yang mendukung window.print(). Untuk testing di desktop, gunakan Chrome atau Chromium-based browser.
terminal COMMANDS Object Reference
COMMANDS object menyediakan set lengkap ESC/POS commands yang terorganisir untuk kontrol printer thermal.
qr_code_2 Cetak QR
Perintah ESC/POS mencetak gambar maupun kode QR dalam bentuk data raster. Pustaka aplikasi sudah menangani konversi bitmap sehingga printer menerima stream ESC/POS siap pakai.
| Fitur | Cara kerja internal | Catatan |
|---|---|---|
| Cetak QR | Data kode QR dibentuk menjadi bitmap kemudian dikirim sebagai raster. | Parameter utama: moduleSize, margin, align. |
Tidak ada escape sequence tunggal yang diekspos publik, tetapi printer menerima stream ESC/POS hasil konversi otomatis.
| Parameter | Tipe | Nilai default | Deskripsi |
|---|---|---|---|
moduleSize |
number | 6 (58mm) / 8 (80mm) | Lebar satu modul QR dalam dot. |
margin |
number | 4 | Margin putih di sekeliling QR (satuan modul). |
ecc |
enum | "M" |
Error correction level (L, M, Q, H). |
keyboard Basic Control Characters
Karakter kontrol dasar untuk komunikasi dengan printer thermal ESC/POS.
LF'\x0a'ESC'\x1b'FS'\x1c'GS'\x1d'US'\x1f'FF'\x0c'DLE'\x10'DC1'\x11'DC4'\x14'EOT'\x04'NUL'\x00'EOL'\n'horizontal_rule Horizontal Line Commands
Garis horizontal untuk pemisah konten pada printer 58mm dan 80mm.
feed Feed Control Sequences
CTL_LF
Print and line feed
CTL_FF
Form feed
CTL_CR
Carriage return
CTL_HT
Horizontal tab
CTL_VT
Vertical tab
line_weight Line Spacing
LS_DEFAULT
Default line spacing
LS_SET
Set line spacing
LS_SET1
Alternative line spacing
settings Hardware Control
HW_INIT
Initialize printer dan reset semua mode
HW_SELECT
Select printer
HW_RESET
Reset printer hardware
point_of_sale Cash Drawer
space_bar Margins
BOTTOM
Set bottom margin
LEFT
Set left margin
RIGHT
Set right margin
content_cut Paper Cutting
format_size Text Formatting
๐ Text Size & Scaling
๐จ Text Decoration
TXT_UNDERL_ON
Underline ON (1-dot)
TXT_UNDERL2_ON
Underline ON
(2-dot)
TXT_UNDERL_OFF
Underline OFF
TXT_BOLD_ON
Bold ON
TXT_BOLD_OFF
Bold OFF
TXT_ITALIC_ON
Italic ON
TXT_ITALIC_OFF
Italic OFF
โ๏ธ Text Alignment
๐ค Font Types
TXT_FONT_A
Font Type A (Default)
TXT_FONT_B
Font Type B
TXT_FONT_C
Font Type C
library_books Panduan Demo Thermal
Ringkasan demo yang aktif beserta potongan kode siap pakai. Tiap kartu mengarah ke halaman demonya sehingga Anda tidak perlu kembali ke playground.
Demo Antrian (Text)
Format dasar tiket antrian. Gunakan Demo Antrian untuk melihat hasil langsung.
const commandParts = [
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
"COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
wrap("NOMOR ANTRIAN\\n"),
"COMMANDS.TEXT_FORMAT.TXT_4SQUARE",
wrap(code + "\\n\\n"),
"COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
wrap("Loket: " + desk + "\\n"),
wrap("Tanggal: " + timestamp + "\\n"),
wrap("Terima kasih, harap menunggu panggilan.\\n\\n\\n")
];
Demo QR Code
Menambahkan COMMANDS.QR() untuk validasi antrian. Lihat hasilnya di Demo QR.
const commandParts = [
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
"COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
wrap("SCAN KODE BERIKUT\\n"),
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
"COMMANDS.TEXT_FORMAT.TXT_4SQUARE",
wrap(code + "\\n\\n"),
"COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
`COMMANDS.QR("${code}", { align: "CENTER", moduleSize: 8, margin: 2, ecc: "M" })`,
wrap("\\nLoket: " + desk + "\\n"),
wrap("Terima kasih\\n\\n")
];
Demo Struk Cafe
Contoh pesanan dengan subtotal, pajak, dan pemotongan kertas. Jalankan di Demo Struk.
const commandParts = [
"COMMANDS.HW_INIT",
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
"COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
wrap("BoostechLab Coffee\\n"),
"COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
wrap("Jl. Contoh No. 123\\n\\n"),
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_LT",
wrap(items.join("\\n")),
"COMMANDS.HR_58MM",
"COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
wrap("TOTAL Rp " + total + "\\n"),
"COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
wrap("\\nMetode: " + payment + "\\n\\n"),
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
wrap("Terima kasih atas kunjungan Anda\\n\\n"),
"COMMANDS.PAPER_FULL_CUT"
];
code Contoh Lengkap
Berikut contoh lengkap implementasi cetak struk dengan semua komponen yang dibutuhkan.
<!DOCTYPE html>
<html>
<head>
<title>IMIN Go-Print Example</title>
</head>
<body>
<h1>Cetak Struk Thermal</h1>
<button id="btnPrint" type="button">Print Struk</button>
<!-- Iframe tersembunyi -->
<iframe id="printSink" style="display:none;"></iframe>
<script>
// Helper function
function wrapCommandText(raw) {
return `'${String(raw).replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n")}'`;
}
// Function kirim ke print
function sendToIframe(commandArray) {
const commandText = commandArray.join("\n");
const printSink = document.getElementById("printSink");
const doc = printSink.contentDocument || printSink.contentWindow.document;
doc.open("text/plain");
doc.write(commandText);
doc.close();
printSink.contentWindow.focus();
setTimeout(() => {
try {
printSink.contentWindow.print();
} catch (err) {
console.error("Print gagal:", err);
}
}, 120);
}
// Event listener
document.getElementById("btnPrint").addEventListener("click", () => {
const now = new Date().toLocaleString("id-ID");
const commandParts = [
"COMMANDS.HW_INIT", // Reset printer
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT", // Center
"COMMANDS.TEXT_FORMAT.TXT_2HEIGHT", // Double height
"COMMANDS.TEXT_FORMAT.TXT_BOLD_ON", // Bold ON
wrapCommandText("TOKO SAYA\n"), // Nama toko
"COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
"COMMANDS.TEXT_FORMAT.TXT_NORMAL",
wrapCommandText("Jl. Contoh No. 123\n"),
wrapCommandText("Telp: 021-12345678\n\n"),
"COMMANDS.HR_58MM", // Garis
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_LT", // Left
wrapCommandText("Tanggal: " + now + "\n\n"),
wrapCommandText("Item 1 Rp 10.000\n"),
wrapCommandText("Item 2 Rp 15.000\n"),
wrapCommandText("Item 3 Rp 20.000\n"),
"COMMANDS.HR_58MM",
"COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
wrapCommandText("TOTAL Rp 45.000\n"),
"COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
wrapCommandText("\n"),
"COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
wrapCommandText("Terima Kasih\n"),
wrapCommandText("Selamat Berbelanja Kembali\n\n\n"),
"COMMANDS.PAPER_FULL_CUT" // Cut paper
];
sendToIframe(commandParts);
});
</script>
</body>
</html>