diff --git a/.gitignore b/.gitignore index 761e59f..8c9e28b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ *.jpeg *.png *.txt -*.json *.xlsx 报销输出/ __pycache__/ diff --git a/差旅报销.py b/差旅报销.py index 0d3317f..7e88aae 100644 --- a/差旅报销.py +++ b/差旅报销.py @@ -221,10 +221,11 @@ def command_fill(args): output_dir = json_path.parent archive_dir = output_dir.parent if output_dir.name == OUTPUT_DIR_NAME else Path(".") - output_file = fill_template(result, output_dir) + output_file = fill_template(result, archive_dir) verify_output(output_file, result) final_archive_dir = finalize_archive_dir(archive_dir, result) - final_output_file = final_archive_dir / OUTPUT_DIR_NAME / output_file.name + final_output_file = final_archive_dir / output_file.name + cleanup_output_dir(final_archive_dir / OUTPUT_DIR_NAME) cleanup_pycache() print(f"完成:{final_output_file}") @@ -314,7 +315,7 @@ def fill_template(result, output_dir): output_file = output_dir / build_output_filename(meta) shutil.copy(TEMPLATE_FILE, output_file) - update_xlsx_cells(output_file, build_cell_values(result)) + update_xlsx_cells(output_file, build_cell_values(result), build_formula_cached_values(result)) return output_file @@ -327,6 +328,7 @@ def build_cell_values(result): "B6": f'{meta["出发地"]}-{meta["目的地"]}', "C6": f'{meta["出差天数"]}天', "D6": meta["出行方式"], + "F6": meta["出差天数"], "H6": expenses["住宿"]["单据张数"], "I6": expenses["住宿"]["金额"], "H7": expenses["饮食"]["单据张数"], @@ -338,7 +340,20 @@ def build_cell_values(result): } -def update_xlsx_cells(xlsx_path, cell_values): +def build_formula_cached_values(result): + summary = result["summary"] + advance = summary["预借差旅费"] + total = summary["报销总额"] + return { + "H2": summary["附件总张数"], + "F9": result["meta"]["出差天数"], + "C10": total, + "H10": max(total - advance, 0), + "H11": max(advance - total, 0), + } + + +def update_xlsx_cells(xlsx_path, cell_values, formula_cached_values): temp_file = NamedTemporaryFile(delete=False, suffix=".xlsx", dir=xlsx_path.parent) temp_path = Path(temp_file.name) temp_file.close() @@ -349,7 +364,7 @@ def update_xlsx_cells(xlsx_path, cell_values): for item in source.infolist(): data = source.read(item.filename) if item.filename == "xl/worksheets/sheet1.xml": - data = update_sheet_xml(data, cell_values) + data = update_sheet_xml(data, cell_values, formula_cached_values) target.writestr(item, data) temp_path.replace(xlsx_path) except Exception: @@ -357,7 +372,7 @@ def update_xlsx_cells(xlsx_path, cell_values): raise -def update_sheet_xml(sheet_xml, cell_values): +def update_sheet_xml(sheet_xml, cell_values, formula_cached_values): namespace = "http://schemas.openxmlformats.org/spreadsheetml/2006/main" ET.register_namespace("", namespace) root = ET.fromstring(sheet_xml) @@ -366,6 +381,11 @@ def update_sheet_xml(sheet_xml, cell_values): if cell is None: raise SystemExit(f"模板缺少单元格:{cell_ref}") set_cell_xml_value(cell, value, namespace) + for cell_ref, value in formula_cached_values.items(): + cell = root.find(f".//{{{namespace}}}c[@r='{cell_ref}']") + if cell is None: + raise SystemExit(f"模板缺少单元格:{cell_ref}") + set_formula_cached_value(cell, value, namespace) return ET.tostring(root, encoding="utf-8", xml_declaration=True) @@ -385,6 +405,18 @@ def set_cell_xml_value(cell, value, namespace): text_node.text = str(value) +def set_formula_cached_value(cell, value, namespace): + cell.attrib.pop("t", None) + value_node = None + for child in cell: + if child.tag == f"{{{namespace}}}v": + value_node = child + break + if value_node is None: + value_node = ET.SubElement(cell, f"{{{namespace}}}v") + value_node.text = format_number_for_excel(value) + + def format_number_for_excel(value): if isinstance(value, int): return str(value) @@ -415,6 +447,11 @@ def unique_archive_dir(path): index += 1 +def cleanup_output_dir(output_dir): + if output_dir.exists(): + shutil.rmtree(output_dir) + + def cleanup_pycache(): pycache_dir = Path("__pycache__") if pycache_dir.exists():