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')