這裡的範例是用匯出的excel檔進行轉換動作
import pandas as pd import json import numpy as np import re import os import tkinter as tk from tkinter import filedialog # **開啟 UI 讓使用者選擇 xls 檔案** root = tk.Tk() root.withdraw() # 隱藏主視窗 xls_file_path = filedialog.askopenfilename(title="選擇 XLS 檔案", filetypes=[("Excel 檔案", "*.xls;*.xlsx")]) if not xls_file_path: print("❌ 未選擇檔案,程式結束") exit() # **取得檔案名稱與路徑** file_dir, file_name = os.path.split(xls_file_path) file_base_name, _ = os.path.splitext(file_name) # **設定輸出檔案名稱** json_output_path = os.path.join(file_dir, f"{file_base_name}.json") excel_output_path = os.path.join(file_dir, f"{file_base_name}_output.xlsx") # **讀取 XLS** df = pd.read_excel(xls_file_path, dtype=str) # 讀取時強制為字串 # **讀取 plist.json(同目錄)** plist_json_path = os.path.join(file_dir, "plist.json") if os.path.exists(plist_json_path): with open(plist_json_path, "r", encoding="utf-8") as f: plist_data = json.load(f) product_price_map = {str(item["產品編號"]): str(item.get("建議售價", "0")) for item in plist_data} else: print("⚠️ 找不到 plist.json,跳過商品價格填補") product_price_map = {} # **清理異常字元** def clean_text(value): if isinstance(value, str): value = value.strip() value = re.sub(r"[\x00-\x1F\x7F-\x9F]", "", value) value = value.replace("\n", " ").replace("\r", " ") value = value.replace('"', "'") return str(value) # 確保返回字串 df = df.map(lambda x: clean_text(str(x)) if pd.notna(x) else "") # **補充「商品結帳價」** for index, row in df.iterrows(): if row["商品結帳價"] == "": product_id = row["商品貨號"] if product_id in product_price_map: df.at[index, "商品結帳價"] = product_price_map[product_id] # **建立 JSON** order_dict = {} for _, row in df.iterrows(): order_id = row["訂單號碼"] # **如果該訂單號碼不存在,先存入第一列的所有欄位** if order_id not in order_dict: order_dict[order_id] = { "order_info": row.to_dict(), "products": [], "order_total": 0 } # **移除商品貨號為空的商品** product_id = row["商品貨號"] if product_id == "": continue quantity = int(row["數量"]) if row["數量"].isdigit() else 1 price = float(row["商品結帳價"]) if row["商品結帳價"].replace('.', '', 1).isdigit() else 0 total_price = price * quantity product_info = { "商品貨號": product_id, "商品結帳價": str(price), "商品名稱": row["商品名稱"] if row["商品名稱"] else row["選項"], "數量": str(quantity) } order_dict[order_id]["products"].append(product_info) order_dict[order_id]["order_total"] += total_price # **加入 "折扣" 產品** for order_id, data in order_dict.items(): payment_total = float(data["order_info"].get("付款總金額", "0") or "0") discount_value = payment_total - data["order_total"] discount_product = { "商品貨號": "P00-000-00", "商品結帳價": str(discount_value), "商品名稱": "折扣", "數量": "1" } data["products"].append(discount_product) # **移除 order_total 欄位** for order_id in order_dict: del order_dict[order_id]["order_total"] # **儲存 JSON** with open(json_output_path, "w", encoding="utf-8") as f: json.dump(order_dict, f, ensure_ascii=False, indent=4) # **轉換為 Excel** order_list = [] for order_id, data in order_dict.items(): order_info = data["order_info"] for product in data["products"]: combined_data = {**order_info, **product} # 先帶入 order_info,再覆蓋 products 內的欄位 order_list.append(combined_data) # **轉換成 DataFrame** order_df = pd.DataFrame(order_list) # **儲存 Excel** order_df.to_excel(excel_output_path, index=False) print(f"✅ JSON 轉換完成,已儲存至 {json_output_path}") print(f"✅ Excel 轉換完成,已儲存至 {excel_output_path}")
說明一下,P00-000-00是進銷中折扣的商品貨號
plist.json格式 (商品的資料庫)
[ { "產品編號": "P01-001-01", "品名規格": "商品1", "(類別名稱)": "分類1", "條碼編號": "55122124121", "建議售價": "1300" } ]
由於Shopline的組合商品,匯出的欄位會是
商品組合 SKU空值 總金額
商品1 SKU
商品2 SKU
(商品1和2伴隨者一堆空值)
因此我才用Python來解套
這裡的使用邏輯,就是如果商品的SKU沒有值,那麼就使用plist.json去撈金額
撈完商品金額後,在商品那裡會把 SKU空值的項目移掉
最後我會用訂單的總金額去扣除所有商品的售價x數量,生成一個折扣 P00-000-00
執行python後會自動存成json及xlsx兩種格式
大概的發想這是這樣,由於我們是用訂單總金額去扣,所以不用去管點數折扣及運費
更進階一點可以用api寫python去拉,會更省事