132 lines
3.0 KiB
Python
132 lines
3.0 KiB
Python
import yaml
|
||
from openpyxl import Workbook
|
||
from openpyxl import load_workbook
|
||
from openpyxl.worksheet.datavalidation import DataValidation
|
||
from appPublic.dictObject import DictObject
|
||
from appPublic.uniqueID import getID
|
||
from ahserver.filestorage import FileStorage
|
||
|
||
def create_colnames():
|
||
r = {}
|
||
fls = ['', 'A', 'B']
|
||
i = 1
|
||
for fl in fls:
|
||
for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
|
||
r[f'{fl}{c}'] = i
|
||
i = i + 1
|
||
return r
|
||
|
||
colnames = create_colnames()
|
||
reverse_colnames = {v:k for k,v in colnames.items()}
|
||
|
||
def write_pattern_xlsx(name: str, fields: dict, data=None) -> str:
|
||
wb = Workbook()
|
||
ws_data = wb.active
|
||
hidden = wb.create_sheet('dict')
|
||
hidden.sheet_status = 'hidden'
|
||
# 3. 写入表头
|
||
headers = []
|
||
c = 1
|
||
opt_id = 0
|
||
for name, f in fields.items():
|
||
if f.type == 'factor':
|
||
continue
|
||
ws_data.cell(row=1, column=c, value=f.label or f.name)
|
||
if f.type == 'bool':
|
||
create_options(ws_data, c, hidden, opt_id, ['=TRUE()', '=FALSE()'])
|
||
opt_id = opt_id + 1
|
||
elif f.options:
|
||
create_options(ws_data, c, hidden, opt_id, f.options)
|
||
opt_id = opt_id + 1
|
||
if data:
|
||
write(ws_data, 2, c, name, data)
|
||
c += 1
|
||
fs = FileStorage()
|
||
if data is None:
|
||
fp = fs._name2path(f'{name}_定价模版.xlsx')
|
||
else:
|
||
write_data(ws_data, fields, data)
|
||
fp = fs._name2path(f'{name}_定价.xlsx')
|
||
|
||
wb.save(fp)
|
||
return fp
|
||
|
||
def write_data(sheet, start_row, col, fname, data):
|
||
r = start_row
|
||
for d in data:
|
||
v = d.get(fname)
|
||
if v:
|
||
sheet.cell(row=r, column=col, value=v)
|
||
r += 1
|
||
|
||
def create_options(ws, dcol, sheet, opt_id, options):
|
||
r = 2
|
||
vc = opt_id + 1
|
||
cnt = len(options) + 1
|
||
for v in options:
|
||
sheet.cell(row=r, column=vc, value=v)
|
||
r = r + 1
|
||
colname = reverse_colnames[vc]
|
||
dv = DataValidation(type="list",
|
||
formula1=f'dict!${colname}$1:${colname}${cnt}',
|
||
allow_blank=True)
|
||
dv.error = '请选择下拉菜单中的有效职位。'
|
||
dv.errorTitle = '输入无效'
|
||
ws.add_data_validation(dv)
|
||
cn = reverse_colnames[dcol]
|
||
dv.add(f'{cn}2:{cn}1048576')
|
||
|
||
def load_xlsx_pricing(xlsxpath):
|
||
wb = load_workbook(xlsxpath)
|
||
ws = wb.active
|
||
d = []
|
||
for row in ws.iter_rows(min_row=2, values_only=True):
|
||
r = {}
|
||
for c, cell in enumerate(row):
|
||
r.update({ws.cell(row=1, column=c+1).value:cell})
|
||
d.append(r)
|
||
return d
|
||
|
||
if __name__ == '__main__':
|
||
fields_str = """model:
|
||
type: str
|
||
label: "模型"
|
||
options:
|
||
- "viduq3-pro"
|
||
- "viduq3-turbo"
|
||
|
||
resolution:
|
||
type: str
|
||
label: "分辨率"
|
||
options:
|
||
- "1024p"
|
||
- "720p"
|
||
- "540p"
|
||
|
||
duration:
|
||
type: int # 建议改为 int 或 str,times 不是标准类型
|
||
label: "时长"
|
||
# 如果时长也有选项,需要补全,例如:
|
||
# options:
|
||
# - 5
|
||
# - 10
|
||
|
||
off_peak:
|
||
type: int # 建议改为 int 或 str,因为值是 0 和 1
|
||
label: "错峰执行"
|
||
options:
|
||
- off_peak # 正常时段
|
||
- normal # 错峰
|
||
price:
|
||
type: float
|
||
label: 单价
|
||
|
||
"""
|
||
"""
|
||
fields = DictObject(**yaml.safe_load(fields_str))
|
||
print(f'{fields=}, {type(fields)=}')
|
||
write_pattern_xlsx(fields)
|
||
"""
|
||
load_xlsx_pricing('./test.xlsx')
|
||
|