UPC-A(Universal Product Code)
UPC-A(Universal Product Code)是常見的需求,主要用於北美市場。
UPC-A 與 EAN-13 的主要差異:
長度:UPC-A 是 12 位數(EAN-13 是 13 位數)。
國家代碼:UPC-A 不像 EAN 有明顯的 3 位國碼,但實際上 EAN-13 的
0開頭即等同於 UPC-A。結構:1 位系統符號 + 5 位廠商碼 + 5 位商品碼 + 1 位檢查碼。
UPC-A 的特點重點:
檢查碼邏輯:UPC-A 的檢查碼計算公式與 EAN-13 略有不同,但
python-barcode套件會自動處理,確保您產生的 12 位碼是合法可掃描的。視覺差異:UPC-A 的數字通常會分開在條碼下方,左邊 1 位、中間 10 位、右邊 1 位。
相容性:所有能掃描 EAN-13 的設備都能掃描 UPC-A,但 UPC-A 通常不包含國家代碼資訊(除非轉成 EAN-13 並補 0)。
import tkinter as tk
from tkinter import ttk, Label, Button, Entry, messagebox, filedialog
import barcode
from barcode.writer import ImageWriter
from PIL import Image, ImageTk
import random
import io
import os
class UPCBarcodeApp:
def __init__(self, root):
self.root = root
self.root.title("UPC-A 批量產生工具 (12位)")
self.root.geometry("750x650")
# 1. UPC 廠商資料庫範例 (北美常見)
self.mfg_data = {
"自定義輸入": "",
"Apple (190198)": "190198",
"Coca-Cola (049000)": "049000",
"Nestle (050000)": "050000",
"Walmart (681131)": "681131",
"Nike (886066)": "886066"
}
main_frame = tk.Frame(self.root, padx=20, pady=10)
main_frame.pack(fill="both", expand=True)
Label(main_frame, text="UPC-A 12-Digit Barcode Generator", font=("Arial", 16, "bold")).pack(pady=10)
# 設定區域
config_frame = tk.LabelFrame(main_frame, text=" 參數設定 ", padx=10, pady=10)
config_frame.pack(fill="x", pady=5)
Label(config_frame, text="選擇廠商/前綴:").grid(row=0, column=0, sticky="w")
self.combo_mfg = ttk.Combobox(config_frame, values=list(self.mfg_data.keys()), state="readonly")
self.combo_mfg.current(0)
self.combo_mfg.grid(row=0, column=1, padx=5, pady=5)
self.combo_mfg.bind("<<ComboboxSelected>>", self.on_mfg_select)
Label(config_frame, text="廠商代碼(建議6位):").grid(row=1, column=0, sticky="w")
self.entry_mfg = Entry(config_frame)
self.entry_mfg.grid(row=1, column=1, padx=5, pady=5)
Label(config_frame, text="產生數量:").grid(row=2, column=0, sticky="w")
self.entry_count = Entry(config_frame)
self.entry_count.insert(0, "5")
self.entry_count.grid(row=2, column=1, padx=5, pady=5)
# 按鈕區
btn_frame = tk.Frame(main_frame)
btn_frame.pack(pady=10)
Button(btn_frame, text="批量產生 UPC", command=self.batch_generate, bg="#E91E63", fg="white", width=15).pack(side="left", padx=5)
Button(btn_frame, text="全部儲存 PNG", command=self.save_all, bg="#2196F3", fg="white", width=15).pack(side="left", padx=5)
# 介面配置:左側清單小,右側預覽大
list_preview_frame = tk.Frame(main_frame)
list_preview_frame.pack(fill="both", expand=True, pady=10)
# 左側清單寬度縮小
self.tree_frame = tk.Frame(list_preview_frame, width=180)
self.tree_frame.pack(side="left", fill="y", padx=(0, 10))
self.tree_frame.pack_propagate(False)
self.tree = ttk.Treeview(self.tree_frame, columns=("code"), show="headings")
self.tree.heading("code", text="UPC 清單")
self.tree.column("code", width=150, anchor="center")
self.tree.pack(fill="both", expand=True)
self.tree.bind("<<TreeviewSelect>>", self.on_tree_select)
# 右側大型預覽
self.preview_container = tk.LabelFrame(list_preview_frame, text=" UPC 大型預覽 (12位) ", bg="#f9f9f9")
self.preview_container.pack(side="right", fill="both", expand=True)
self.preview_label = Label(self.preview_container, bg="white")
self.preview_label.pack(padx=15, pady=15, fill="both", expand=True)
self.generated_barcodes = {}
def on_mfg_select(self, event):
selected = self.combo_mfg.get()
code = self.mfg_data[selected]
self.entry_mfg.delete(0, tk.END)
self.entry_mfg.insert(0, code)
def generate_single_upc(self, mfg_code):
# UPC-A 需要 11 位(+1位自動生成的檢查碼 = 12位)
rem_len = 11 - len(mfg_code)
product_part = "".join([str(random.randint(0, 9)) for _ in range(rem_len)])
full_payload = mfg_code + product_part
# 使用 python-barcode 的 upca 模式
upc = barcode.get('upca', full_payload, writer=ImageWriter())
buffer = io.BytesIO()
upc.write(buffer)
buffer.seek(0)
return upc.get_fullcode(), Image.open(buffer)
def batch_generate(self):
mfg = self.entry_mfg.get().strip()
try:
count = int(self.entry_count.get())
if not mfg.isdigit() or len(mfg) > 11: raise ValueError()
except:
messagebox.showerror("錯誤", "請輸入有效的數字碼(1-11位)與產生數量")
return
for i in self.tree.get_children(): self.tree.delete(i)
self.generated_barcodes.clear()
for _ in range(count):
code, img = self.generate_single_upc(mfg)
self.generated_barcodes[str(code)] = img
self.tree.insert("", "end", values=(code,))
if self.tree.get_children():
self.tree.selection_set(self.tree.get_children()[0])
def on_tree_select(self, event):
selection = self.tree.selection()
if selection:
code = self.tree.item(selection[0])['values'][0]
# 強制轉為字串搜尋(處理 0 開頭問題)
code_str = str(code).zfill(12)
pil_img = self.generated_barcodes.get(code_str)
if pil_img:
self.root.update_idletasks()
view_w = self.preview_label.winfo_width()
# 放大條碼預覽
target_w = max(view_w - 30, 400)
w, h = pil_img.size
scale = target_w / w
display_img = pil_img.resize((int(w * scale), int(h * scale)), Image.Resampling.LANCZOS)
tk_img = ImageTk.PhotoImage(display_img)
self.preview_label.config(image=tk_img)
self.preview_label.image = tk_img
def save_all(self):
if not self.generated_barcodes: return
folder = filedialog.askdirectory(title="選擇儲存資料夾")
if folder:
for code, img in self.generated_barcodes.items():
img.save(os.path.join(folder, f"UPCA_{code}.png"))
messagebox.showinfo("成功", f"批量儲存完成!")
if __name__ == "__main__":
root = tk.Tk()
app = UPCBarcodeApp(root)
root.mainloop()

沒有留言:
張貼留言