ปัญหาการพิมพ์บนเบราว์เซอร์
หากคุณเคยลองพิมพ์ใบเสร็จจากเว็บแอป คุณจะรู้ถึงความยุ่งยาก: window.print() จะเปิดกล่องโต้ตอบการพิมพ์, แสดงผลหน้าเว็บเป็น PDF, และไม่มีการรองรับคำสั่ง ESC/POS เช่น การตัดอัตโนมัติ หรือการกำหนดความกว้างกระดาษเองเลย
สำหรับเครื่องพิมพ์ใบเสร็จความร้อน นี่คือปัญหาใหญ่ คุณจำเป็นต้องมี:
- การพิมพ์แบบเงียบ — ไม่มีกล่องโต้ตอบ ไม่มีการโต้ตอบจากผู้ใช้
- คำสั่ง ESC/POS — สำหรับการตัดอัตโนมัติ, ตัวหนา, การจัดตำแหน่ง, บาร์โค้ด
- การเข้ารหัสที่เชื่อถือได้ — UTF-8 ไปยังหน้าโค้ดที่ถูกต้องสำหรับเครื่องพิมพ์ของคุณ
- การรองรับข้ามแพลตฟอร์ม — Mac, Windows, Linux
ทางออกคือ WebSocket bridge ในเครื่อง — แอปพลิเคชันพื้นหลังขนาดเล็กที่ทำงานบนคอมพิวเตอร์ของผู้ใช้ รับงานพิมพ์จากเว็บแอปของคุณ และส่งคำสั่ง ESC/POS ดิบไปยังเครื่องพิมพ์
WebSocket Bridge ทำงานอย่างไร
Your Web App → WebSocket (ws://localhost:8765) → Print Agent → Thermal Printer
ขั้นตอนง่ายๆ:
- เว็บแอปของคุณเปิดการเชื่อมต่อ WebSocket ไปยัง ws://localhost:8765
- คุณส่ง JSON payload ที่อธิบายใบเสร็จ
- Print Agent แปลงเป็น ESC/POS และส่งไปยังเครื่องพิมพ์
- เครื่องพิมพ์พิมพ์แบบเงียบ — ไม่มีกล่องโต้ตอบ ไม่มีการโต้ตอบกับไดรเวอร์
MenuForma Print Agent นำสะพานนี้ไปใช้งาน มันฟรี เป็นโอเพนซอร์ส และทำงานบน Mac, Windows และ Linux
การอ้างอิง API
การเชื่อมต่อ
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => {
console.log('Print Agent connected');
};
ws.onerror = () => {
console.log('Print Agent not running');
};
ตรวจสอบสถานะ Agent
ส่ง ping เพื่อตรวจสอบว่า Agent กำลังทำงานอยู่:
ws.send(JSON.stringify({ type: 'ping' }));
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'pong') {
console.log('Agent version:', data.version);
}
};
พิมพ์ใบเสร็จ
const receipt = {
type: 'print',
printer: 'auto', // or specific IP like '192.168.1.100'
data: {
storeName: 'My Restaurant',
storeAddress: '123 Main St',
orderNumber: '#1042',
tableNumber: 'Table 5',
items: [
{ name: 'Margherita Pizza', qty: 1, price: 14.90 },
{ name: 'Sparkling Water', qty: 2, price: 3.50 },
],
subtotal: 21.90,
tax: 1.97,
total: 23.87,
paymentMethod: 'Card',
footer: 'Thank you for dining with us!',
}
};
ws.send(JSON.stringify(receipt));
ตัวอย่างการผสานรวม 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); // retry
};
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 };
}
การผสานรวมกับ Shopify
สำหรับร้านค้า Shopify คุณสามารถเรียกใช้การพิมพ์จาก webhook ของคำสั่งซื้อ หรือจากส่วนขยายของเบราว์เซอร์:
// ในหน้าร้านค้า Shopify หรือส่วนขยายผู้ดูแลระบบของคุณ
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,
}
}));
};
}
การกำหนดค่าเครื่องพิมพ์
ฟิลด์ "printer" ในเพย์โหลดการพิมพ์ยอมรับค่าดังนี้:
| ค่า | คำอธิบาย |
|---|---|
| "auto" | ใช้เครื่องพิมพ์ที่กำหนดค่าไว้ในการตั้งค่า Print Agent |
| "192.168.1.100" | เชื่อมต่อโดยตรงกับเครื่องพิมพ์เครือข่ายด้วย IP |
| "USB" | ใช้เครื่องพิมพ์ USB ที่ตรวจพบเครื่องแรก |
การจัดการข้อผิดพลาด
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);
// แสดง UI สำรองหรือลองใหม่
}
};
การตรวจจับว่ามีการติดตั้ง Print Agent หรือไม่
ก่อนที่จะแสดงฟังก์ชันการพิมพ์ใน UI ของคุณ ให้ตรวจสอบว่าเอเจนต์กำลังทำงานอยู่หรือไม่:
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);
};
});
}
// การใช้งาน
const agentAvailable = await isPrintAgentAvailable();
if (!agentAvailable) {
// แสดงข้อความแจ้งให้ดาวน์โหลด
window.open('/print-agent', '_blank');
}
ดาวน์โหลด Print Agent
MenuForma Print Agent นั้นฟรีและพร้อมใช้งานสำหรับ Mac, Windows และ Linux รองรับเครื่องพิมพ์เทอร์มอลแบบ USB, เครือข่าย และ Bluetooth และใช้งาน WebSocket API เต็มรูปแบบตามที่อธิบายไว้ในคู่มือนี้
สำหรับเอกสารประกอบ API ฉบับเต็มและซอร์สโค้ดโอเพนซอร์ส โปรดเยี่ยมชม หน้า Print Agent
Related Articles
- ฝ่าวิกฤตต้นทุนพุ่งปี 2025: ทำไมร้านอาหารไทยต้องพึ่งพาระบบ QR Code สั่งอาหารเพื่อความอยู่รอด
- ถอดรหัสความสำเร็จจาก LINE FOOD TECH 2025: สร้างประสบการณ์ไร้รอยต่อด้วยเทคโนโลยีสั่งอาหาร
- เจาะเทรนด์เทคโนโลยีร้านอาหารไทยปี 2025: ยกระดับบริการด้วยระบบสั่งอาหารไร้สัมผัส