dotfiles/VSCodium/User/History/-2f7fe65f/AecY.py
2026-06-19 14:29:55 +02:00

134 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
populate_template.py
Script to copy data from a production order Excel file into an ODS template
and save the result as a new ODS file named after the value in cell A2.
Requirements:
pip install openpyxl odfpy
"""
import sys
from pathlib import Path
from openpyxl import load_workbook
from odf.opendocument import load, OpenDocumentSpreadsheet
from odf.table import Table, TableRow, TableCell
from odf.text import P
# ----------------------------------------------------------------------
# Configuration adjust if your filenames differ
# ----------------------------------------------------------------------
SOURCE_XLSX = Path("Production Order (mrp.production).xlsx")
TEMPLATE_ODS = Path("A4004_v3.0-260617.ods")
OUTPUT_DIR = Path(".") # current directory; change if you prefer another location
# ----------------------------------------------------------------------
# Helper functions for ODS manipulation
# ----------------------------------------------------------------------
def get_cell(table: Table, col_idx: int, row_idx: int) -> TableCell:
"""Return the TableCell at (col_idx, row_idx) 0based indices."""
rows = table.getElementsByType(TableRow)
if row_idx >= len(rows):
raise IndexError(f"Row {row_idx} out of range")
cells = rows[row_idx].getElementsByType(TableCell)
if col_idx >= len(cells):
raise IndexError(f"Column {col_idx} out of range")
return cells[col_idx]
def set_cell_value(table: Table, col_idx: int, row_idx: int, value: str):
"""Write a string value into the specified cell."""
cell = get_cell(table, col_idx, row_idx)
# Clear existing content
for child in list(cell.childNodes):
cell.removeChild(child)
# Insert new text
cell.addElement(P(text=str(value)))
def col_letter_to_index(letter: str) -> int:
"""Convert Excelstyle column letter (A=0, B=1, …) to zerobased index."""
return ord(letter.upper()) - ord('A')
# ----------------------------------------------------------------------
# Main processing
# ----------------------------------------------------------------------
def main() -> None:
# 1. Load source workbook
wb = load_workbook(SOURCE_XLSX, data_only=True)
ws = wb.active
# Helper to find a cell containing a given substring (casesensitive)
def find_cell_containing(text: str):
for row in ws.iter_rows(values_only=False):
for cell in row:
if isinstance(cell.value, str) and text in cell.value:
return cell
return None
# ------------------------------------------------------------------
# Extract required values from the source file
# ------------------------------------------------------------------
# a) FA suffix (column B)
fa_suffix = None
for cell in ws["B"]:
if isinstance(cell.value, str) and cell.value.startswith("FA-"):
fa_suffix = cell.value.split("FA-")[1].strip()
break
if fa_suffix is None:
sys.exit("Error: Could not find a cell in column B starting with 'FA-'")
# b) Adjacent values for the component strings
def get_right_adjacent(search_str: str) -> str:
match = find_cell_containing(search_str)
if not match:
sys.exit(f"Error: Could not find cell containing '{search_str}'")
right_cell = ws.cell(row=match.row, column=match.column + 1)
return right_cell.value if right_cell.value is not None else ""
barebone_val = get_right_adjacent("All / Components / Barebone")
gpu_val = get_right_adjacent("All / Components / GPU")
ram_val = get_right_adjacent("All / Components / RAM")
cpu_val = get_right_adjacent("All / Components / CPU")
ssd_val = get_right_adjacent("All / Components / SSD")
raid_val = get_right_adjacent("All / Components / RAID")
# c) File name from A2
file_name_cell = ws["A2"]
if file_name_cell.value is None:
sys.exit("Error: Cell A2 in source file is empty")
output_name = f"{file_name_cell.value}.ods"
# ------------------------------------------------------------------
# Load ODS template and write values
# ------------------------------------------------------------------
ods_doc: OpenDocumentSpreadsheet = load(str(TEMPLATE_ODS))
# Assuming the template has a single table; adjust index if needed
table: Table = ods_doc.spreadsheet.getElementsByType(Table)[0]
# Mapping of target ranges (topleft cell only) → value
# (col_letter, row_number) are 1based as in Excel/ODS UI
targets = {
("B", 1): fa_suffix, # B1:C2 → write to B1
("C", 10): barebone_val, # C10:D10 → write to C10
("C", 20): gpu_val, # C20:D23 → write to C20
("C", 12): ram_val, # C12:D19 → write to C12
("C", 11): cpu_val, # C11:D11 → write to C11
("C", 24): ssd_val, # C24:D25 → write to C24
("C", 27): raid_val, # C27:D27 → write to C27
}
for (col_letter, row_number), value in targets.items():
col_idx = col_letter_to_index(col_letter)
row_idx = row_number - 1 # zerobased for our helper
set_cell_value(table, col_idx, row_idx, value)
# ------------------------------------------------------------------
# Save the modified document
# ------------------------------------------------------------------
output_path = OUTPUT_DIR / output_name
ods_doc.save(str(output_path))
print(f"Successfully created: {output_path}")
if __name__ == "__main__":
main()