Masalah Pencetakan Pelayar
Jika anda pernah cuba mencetak resit dari aplikasi web, anda tahu kesukarannya: window.print() membuka dialog cetak, memaparkan halaman sebagai PDF, dan tiada sokongan untuk arahan ESC/POS seperti potong automatik atau lebar kertas tersuai.
Untuk pencetak resit terma, ini adalah masalah besar. Anda memerlukan:
- Pencetakan senyap — tiada dialog, tiada interaksi pengguna
- Arahan ESC/POS — untuk potong automatik, teks tebal, penjajaran, kod bar
- Pengekodan yang boleh dipercayai — UTF-8 ke halaman kod yang betul untuk pencetak anda
- Sokongan merentas platform — Mac, Windows, Linux
Penyelesaiannya adalah jambatan WebSocket tempatan — aplikasi latar belakang kecil yang berjalan pada komputer pengguna, menerima tugas cetakan dari aplikasi web anda, dan menghantar arahan ESC/POS mentah ke pencetak.
Bagaimana Jambatan WebSocket Berfungsi
Aplikasi Web Anda → WebSocket (ws://localhost:8765) → Ejen Cetak → Pencetak Terma
Alirannya mudah:
- Aplikasi web anda membuka sambungan WebSocket ke ws://localhost:8765
- Anda menghantar muatan JSON yang menerangkan resit
- Ejen Cetak menukarnya kepada ESC/POS dan menghantarnya ke pencetak
- Pencetak mencetak secara senyap — tiada dialog, tiada interaksi pemacu
MenuForma Print Agent melaksanakan jambatan ini. Ia percuma, sumber terbuka, dan berjalan pada Mac, Windows, dan Linux.
Rujukan API
Sambungan
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => {
console.log('Ejen Cetak disambungkan');
};
ws.onerror = () => {
console.log('Ejen Cetak tidak berjalan');
};
Semak Status Ejen
Hantar ping untuk mengesahkan ejen sedang berjalan:
ws.send(JSON.stringify({ type: 'ping' }));
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'pong') {
console.log('Versi ejen:', data.version);
}
};
Cetak Resit
const receipt = {
type: 'print',
printer: 'auto', // atau IP tertentu seperti '192.168.1.100'
data: {
storeName: 'Restoran Saya',
storeAddress: '123 Jalan Utama',
orderNumber: '#1042',
tableNumber: 'Meja 5',
items: [
{ name: 'Pizza Margherita', qty: 1, price: 14.90 },
{ name: 'Air Berkarbonat', qty: 2, price: 3.50 },
],
subtotal: 21.90,
tax: 1.97,
total: 23.87,
paymentMethod: 'Kad',
footer: 'Terima kasih kerana menjamu selera bersama kami!',
}
};
ws.send(JSON.stringify(receipt));
Contoh Integrasi React
import { useEffect, useRef, useCallback, useState } from 'react';
function usePrintAgent() {
const wsRef = useRef(null);
const [connected, setConnected] = useState(false);
useEffect(() => {
const connect = () => {
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => setConnected(true);
ws.onclose = () => {
setConnected(false);
setTimeout(connect, 3000); // cuba semula
};
wsRef.current = ws;
};
connect();
return () => wsRef.current?.close();
}, []);
const print = useCallback((receiptData) => {
if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
throw new Error('Print Agent not connected');
}
wsRef.current.send(JSON.stringify({ type: 'print', data: receiptData }));
}, []);
return { connected, print };
}
Integrasi Shopify
Untuk kedai Shopify, anda boleh mencetuskan pencetakan daripada cangkuk web Pesanan atau daripada sambungan pelayar:
// Dalam etalase Shopify atau sambungan pentadbir anda
async function printShopifyOrder(order) {
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'print',
data: {
storeName: order.shop_name,
orderNumber: order.name,
items: order.line_items.map(item => ({
name: item.title,
qty: item.quantity,
price: parseFloat(item.price),
})),
total: parseFloat(order.total_price),
paymentMethod: order.payment_gateway,
}
}));
};
}
Konfigurasi Pencetak
Medan "printer" dalam muatan cetakan menerima:
| Nilai | Penerangan |
|---|---|
| "auto" | Gunakan pencetak yang dikonfigurasi dalam tetapan Print Agent |
| "192.168.1.100" | Sambung terus ke pencetak rangkaian melalui IP |
| "USB" | Gunakan pencetak USB pertama yang dikesan |
Pengendalian Ralat
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.type === 'print_success') {
console.log('Printed successfully');
} else if (response.type === 'print_error') {
console.error('Print failed:', response.error);
// Tunjukkan UI sandaran atau cuba semula
}
};
Mengesan Sama Ada Print Agent Dipasang
Sebelum menunjukkan fungsi cetakan dalam UI anda, semak sama ada ejen sedang berjalan:
async function isPrintAgentAvailable() {
return new Promise((resolve) => {
const ws = new WebSocket('ws://localhost:8765');
const timeout = setTimeout(() => {
ws.close();
resolve(false);
}, 1000);
ws.onopen = () => {
clearTimeout(timeout);
ws.close();
resolve(true);
};
ws.onerror = () => {
clearTimeout(timeout);
resolve(false);
};
});
}
// Penggunaan
const agentAvailable = await isPrintAgentAvailable();
if (!agentAvailable) {
// Tunjukkan gesaan muat turun
window.open('/print-agent', '_blank');
}
Muat Turun Print Agent
MenuForma Print Agent adalah percuma dan tersedia untuk Mac, Windows, dan Linux. Ia menyokong pencetak terma USB, rangkaian, dan Bluetooth, dan melaksanakan API WebSocket penuh yang diterangkan dalam panduan ini.
Untuk dokumentasi API penuh dan kod sumber terbuka, lawati halaman Print Agent.
Related Articles
- Menu Kod QR di Restoran Malaysia: Reaksi Bercampur Pelanggan Berbilang Generasi
- Bagaimana AI dan Digitalisasi Mengubah Landskap F&B Malaysia pada 2025
- Jualan Digital Mencecah 28.5%: Masa Depan Restoran dan Dapur Awan di Malaysia