This commit is contained in:
Viet An
2026-06-26 13:34:01 +07:00
parent f759ca49d5
commit 1262dc6d82
4 changed files with 39 additions and 30 deletions

View File

@@ -0,0 +1,8 @@
SIZE 76 mm,95 mm
GAP 2 mm,0
DIRECTION 1
DENSITY 8
CLS
{items_block}
PRINT 1,1
CUT

View File

@@ -1,6 +1,24 @@
import win32print import win32print
import sys import sys
import json import json
import os
def load_template(filename):
script_dir = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(script_dir, filename)
with open(path, "r", encoding="utf-8") as f:
return f.read()
def money(n):
return f"{int(float(n)):,}" if n is not None else "0"
def build_item_block(item, y_offset):
name = item['name']
price = money(item['price'])
imei = item['imei']
return f'''TEXT 20,{y_offset},"3",0,1,1,"{name}"
TEXT 20,{y_offset+30},"2",0,1,1,"{price} VND"
BARCODE 20,{y_offset+60},"128",50,1,0,2,2,"{imei}"'''
def print_barcode(tspl_content, printer_name="Xprinter XP-350BM"): def print_barcode(tspl_content, printer_name="Xprinter XP-350BM"):
h = win32print.OpenPrinter(printer_name) h = win32print.OpenPrinter(printer_name)
@@ -15,18 +33,18 @@ def print_barcode(tspl_content, printer_name="Xprinter XP-350BM"):
if __name__ == "__main__": if __name__ == "__main__":
data = json.loads(sys.argv[1]) data = json.loads(sys.argv[1])
items = data['items'] # list of {name, price, imei}
tspl = f''' spacing = 180 # vertical gap between each stacked label, adjust if overlapping/too sparse
SIZE 50 mm,40 mm blocks = []
GAP 2 mm,0 for i, item in enumerate(items):
DIRECTION 1 y_offset = 20 + (i * spacing)
DENSITY 8 blocks.append(build_item_block(item, y_offset))
CLS
TEXT 20,15,"3",0,1,1,"{data['name']}" items_block = "\n\n".join(blocks)
TEXT 20,70,"1",0,1,1,"Price: {data['price']} VND"
BARCODE 20,140,"128",50,1,0,2,2,"{data['imei']}" template = load_template("barcode_template.txt")
PRINT 1,1 tspl = template.replace("{items_block}", items_block)
'''.strip()
print_barcode(tspl) print_barcode(tspl)
print("Sent to printer.") print("Sent to printer.")

View File

@@ -1,17 +0,0 @@
SIZE 50 mm,40 mm
GAP 2 mm,0
DIRECTION 1
DENSITY 8
CLS
TEXT 20,15,"3",0,1,1,"CellphoneS Store"
TEXT 20,45,"2",0,1,1,"iPhone 15 Pro Max 256GB"
TEXT 20,70,"2",0,1,1,"Color: Natural Titanium"
TEXT 20,95,"1",0,1,1,"Price: 29,990,000 VND"
TEXT 20,115,"1",0,1,1,"Warranty: 12 months"
BARCODE 20,140,"128",50,1,0,2,2,"SKU123456789"
QRCODE 280,140,"L",4,"A",0,"https://example.com/p/123456789"
PRINT 1,1

View File

@@ -6,10 +6,10 @@ const execFileAsync = promisify(execFile);
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
const body = await readBody(event); const body = await readBody(event);
const { name, imei, price } = body; const { items } = body;
const scriptPath = path.join(process.cwd(), "print", "print_barcode.py"); const scriptPath = path.join(process.cwd(), "print", "print_barcode.py");
const payload = JSON.stringify({ name, imei, price }); const payload = JSON.stringify({ items });
try { try {
const { stdout } = await execFileAsync("python", [scriptPath, payload]); const { stdout } = await execFileAsync("python", [scriptPath, payload]);