gaoluyang
12 小时以前 e40a608ef9bf51db294d8eefada6a8e2e80cebca
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import openpyxl,json,hashlib,collections
from pathlib import Path
from datetime import datetime
from decimal import Decimal
P=Path('scripts/quotation-import');P.mkdir(exist_ok=True)
source=Path('D:/WechatRecord/xwechat_files/wxid_vmeut7wztkbp22_1546/temp/RWTemp/2026-10/c40afdcfa98e2b4561823e6babbefa33/销售报价单_2026.8.1-10.11.xlsx')
w=openpyxl.load_workbook(source,data_only=True)
quotes=[];products=collections.Counter();excluded=[]
def dec(v):return str(Decimal(str(v))) if v is not None else None
for s in w:
 if '汇总' in s.title or s.title=='编制说明':excluded.append(s.title);continue
 rows=list(s.values)
 assert rows[0][0]=='销 售 报 价 单',s.title
 h=dict(sheet=s.title,no=rows[1][1],owner=rows[1][4],quotation_time=rows[1][7].isoformat(sep=' '),valid_until=rows[1][9].isoformat(sep=' '),customer=rows[2][1],business=rows[2][5],contact=rows[2][9],tax=dec(rows[3][1]),remark=rows[3][4],items=[])
 assert rows[5][:10]==('序号','产品名称','规格型号','单位','辅单位1','辅单位2','原价(元)','报价(元)','数量','合计(元)'),s.title
 for n,r in enumerate(rows[6:],7):
  if isinstance(r[0],(int,float)):
   assert r[1] and r[2] and r[3],(s.title,n,r)
   x=dict(row=n,line=int(r[0]),name=r[1],specification=r[2],unit=r[3],unit2=r[4],unit3=r[5],original_price=dec(r[6]),price=dec(r[7]),count=dec(r[8]),total=dec(r[9]))
   h['items'].append(x);products[(x['name'],x['specification'],x['unit'])]+=1
  elif any(v is not None for v in r):
   h.setdefault('footers',[]).append(dict(row=n,values=list(r)))
 assert h['items'],s.title
 quotes.append(h)
data=dict(source=str(source),sha256=hashlib.sha256(source.read_bytes()).hexdigest(),excluded_sheets=excluded,quotes=quotes)
(P/'source.json').write_text(json.dumps(data,ensure_ascii=False,indent=2,default=str),encoding='utf-8')
(P/'source-products.json').write_text(json.dumps([dict(name=k[0],specification=k[1],unit=k[2],occurrences=v) for k,v in products.items()],ensure_ascii=False,indent=2),encoding='utf-8')
print('Quotes',len(quotes),'Lines',sum(len(x['items']) for x in quotes),'Unique products',len(products),'Excluded',excluded)
print('Owners',collections.Counter(x['owner'] for x in quotes))
print('Taxes',collections.Counter(x['tax'] for x in quotes))
print('Totals',sum(Decimal(x['total']) for q in quotes for x in q['items']))
print('Footers',quotes[0].get('footers'))