| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import sys
- import os
- import time
- from openpyxl import load_workbook
- def get_resource_path(relative_path):
- """ 获取资源绝对路径,兼容开发环境和 PyInstaller 打包环境 """
- if hasattr(sys, '_MEIPASS'):
- # PyInstaller 打包后的临时解压路径
- return os.path.join(sys._MEIPASS, relative_path)
- # 开发环境下的路径
- base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- return os.path.join(base_dir, relative_path)
- def get_existing_info(file_path):
- """
- 读取已有文件中的链接和最后一行编码
- """
- links = set()
- last_code = 0
- if not os.path.exists(file_path):
- return links, last_code
-
- try:
- wb = load_workbook(file_path, data_only=True)
- ws = wb.active
- # 假设 A 列是编码,K 列是链接
- for r in range(3, ws.max_row + 1):
- code_val = ws.cell(row=r, column=1).value
- link_val = ws.cell(row=r, column=11).value
-
- if link_val:
- links.add(str(link_val).strip())
-
- if isinstance(code_val, (int, float)):
- last_code = max(last_code, int(code_val))
- except:
- pass
- return links, last_code
- def append_to_template(products, output_path, status_callback=None):
- """
- 将产品数据追加写入到指定的 Excel 文件中。
- 增加文件占用检测:如果文件被打开,则暂停任务直到关闭。
- 并在第二个 Sheet 中记录商品总数。
- """
- template_path = get_resource_path(os.path.join('templates', '【进价】产品信息空表.xlsx'))
-
- if not os.path.exists(template_path):
- template_path = os.path.join('templates', '【进价】产品信息空表.xlsx')
- if not os.path.exists(template_path):
- raise FileNotFoundError(f"未找到核心模板文件: {template_path}")
- if os.path.exists(output_path):
- wb = load_workbook(output_path)
- else:
- os.makedirs(os.path.dirname(output_path), exist_ok=True)
- wb = load_workbook(template_path)
-
- # 1. 写入主数据 Sheet
- ws = wb.active
-
- # 寻找起始行 (基于第 11 列“产品链接”进行判定,防止覆盖)
- start_row = 3
- for r in range(3, ws.max_row + 2):
- val_link = ws.cell(row=r, column=11).value
- if val_link is None or str(val_link).strip() == "":
- start_row = r
- break
- else:
- start_row = ws.max_row + 1
-
- # 获取当前已有的链接集合,用于后续统计唯一商品
- existing_links = set()
- for r in range(3, start_row):
- link = ws.cell(row=r, column=11).value
- if link: existing_links.add(str(link).strip())
- for i, product in enumerate(products):
- row = start_row + i
- ws.cell(row=row, column=1, value=row - 2)
- ws.cell(row=row, column=2, value=product.get('category', ''))
- ws.cell(row=row, column=3, value=product.get('brand', ''))
- ws.cell(row=row, column=4, value=product.get('name', ''))
- ws.cell(row=row, column=5, value=product.get('color', ''))
- ws.cell(row=row, column=6, value=product.get('spec', ''))
- ws.cell(row=row, column=7, value=product.get('material', ''))
- ws.cell(row=row, column=8, value=product.get('price', ''))
- ws.cell(row=row, column=9, value=product.get('moq', ''))
- ws.cell(row=row, column=10, value=product.get('wholesale_price', ''))
- ws.cell(row=row, column=11, value=product.get('link', ''))
- ws.cell(row=row, column=12, value=product.get('supplier', ''))
-
- link = product.get('link')
- if link: existing_links.add(str(link).strip())
- # 2. 写入/更新计数 Sheet (第二个 Sheet)
- sheet_names = wb.sheetnames
- if len(sheet_names) < 2:
- wb.create_sheet("统计状态")
-
- ws_stat = wb["统计状态"]
- ws_stat.cell(row=1, column=1, value="已解析商品总数")
- ws_stat.cell(row=1, column=2, value=len(existing_links))
- ws_stat.cell(row=2, column=1, value="最后更新时间")
- ws_stat.cell(row=2, column=2, value=time.strftime("%Y-%m-%d %H:%M:%S"))
- # 3. 占用检测保存循环
- while True:
- try:
- wb.save(output_path)
- if status_callback:
- status_callback(False, "写入成功")
- break
- except PermissionError:
- msg = "文件被占用,请关闭 Excel"
- print(f"[!] {msg}: {output_path}")
- if status_callback:
- status_callback(True, msg)
- time.sleep(3)
|