diff --git a/.gitignore b/.gitignore index c8dda84..1b77bb4 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ __pycache__/ dist_32bit/ *.zip ./build_32bit/ -build_32bit/ \ No newline at end of file +build_32bit/ +зу/ \ No newline at end of file diff --git a/main.py b/main.py index 3cbed68..6da6a8c 100644 --- a/main.py +++ b/main.py @@ -69,6 +69,24 @@ def run_processing(table1_path: str, table2_path: str, mif_dir: str, log_callback(f" [{len(generated)+len(errors)+1}/{total}] {filename} ...", end="") try: scheme_png = t3_images.get(str(zu_file).strip()) + # fallback: если в таблице 3 нет изображения, попробуем найти файл в папке с MIF (mif_dir) + if scheme_png is None: + found = None + mif_root = Path(mif_dir) + if mif_root.exists(): + for ext in ('.png', '.jpg', '.jpeg'): + for p in mif_root.rglob(f'*{str(zu_file).strip()}*'): + if p.suffix.lower() == ext: + found = p + break + if found: + break + if found: + try: + scheme_png = found.read_bytes() + log_callback(f" image loaded from {found}") + except Exception: + scheme_png = None oks_file_name = str(t2_row[10]).strip() if len(t2_row) > 10 and t2_row[10] else "" oks_scheme_png = t3_images.get(oks_file_name) if oks_file_name else None zu_scale = t3_scales.get(str(zu_file).strip()) @@ -142,12 +160,12 @@ class App(tk.Tk): # Дефолты base = Path(__file__).parent - data = base / "data" / "Исх.данные" + data = base / "data" self.var_t1.set(str(data / "Таблица1 КИ-Неустроева.xlsx")) - self.var_t2.set(str(data / "Таблица 2 Перечень выявленных исх.данные.xlsx")) - self.var_t3.set(str(data / "Таблица 3 ( для схем).xlsx")) - self.var_mif.set(str(data / "1. 74 34 0400007 ГК вымпел-73")) - self.var_template.set(str(base / "data" / "ШАБЛОН ВЫЯВЛЕННЫЕ-1.xlsx")) + self.var_t2.set(str(data / "Таблица 2.xlsx")) + self.var_t3.set("") + self.var_mif.set(str(data)) + self.var_template.set(str(data / "ШАБЛОН ВЫЯВЛЕННЫЕ-2.xlsx")) self.var_output.set(str(base / "output")) # Прогресс-бар diff --git a/services/data_loader.py b/services/data_loader.py index 96d2460..7bf706f 100644 --- a/services/data_loader.py +++ b/services/data_loader.py @@ -69,7 +69,7 @@ def load_table3(path: str): scales = {} # zu_name → масштаб (строка из c1 третьей строки блока) for i, row in enumerate(ws.iter_rows(values_only=True), start=1): zu_name = row[5] if len(row) > 5 else None - if zu_name and str(zu_name).strip().startswith("выявл"): + if zu_name and str(zu_name).strip(): zu_name = str(zu_name).strip() zu_by_row[i] = zu_name # масштаб — третья строка блока (header+2) diff --git a/services/form_filler.py b/services/form_filler.py index 4a4d826..ee90f26 100644 --- a/services/form_filler.py +++ b/services/form_filler.py @@ -3,6 +3,7 @@ import copy import datetime import io +from pathlib import Path from openpyxl import load_workbook from openpyxl.drawing.image import Image as XlImage @@ -225,12 +226,26 @@ def _embed_image(ws, png_bytes: bytes, anchor_row: int, pre_rows: int) -> int: # В отличие от TwoCellAnchor, LibreOffice не пересчитывает позицию # через сумму высот строк → картинка не уплывает вверх при склейке форм. img = XlImage(io.BytesIO(png_bytes)) - cell_anchor = OneCellAnchor() - cell_anchor._from = AnchorMarker(col=0, colOff=0, row=anchor_row - 1, rowOff=0) - cell_anchor.ext.cx = int(pt_w * 12700) # pt → EMU - cell_anchor.ext.cy = int(pt_h * 12700) - img.anchor = cell_anchor - ws.add_image(img) + # Установим размер картинки в пикселях с учётом масштабирования + scale = 1.0 + if pt_w > MAX_PT_W: + scale = MAX_PT_W / pt_w + img.width = int(px_w * scale) + img.height = int(px_h * scale) + + # Добавляем изображение привязкой к ячейке A{anchor_row} + try: + ws.add_image(img, f"A{anchor_row}") + except Exception: + try: + cell_anchor = OneCellAnchor() + cell_anchor._from = AnchorMarker(col=0, colOff=0, row=anchor_row - 1, rowOff=0) + cell_anchor.ext.cx = int(pt_w * 12700) # pt → EMU + cell_anchor.ext.cy = int(pt_h * 12700) + img.anchor = cell_anchor + ws.add_image(img) + except Exception: + pass return -rows_to_delete # отрицательное смещение: строки были удалены diff --git a/services/mif_processor.py b/services/mif_processor.py index 7ceb10f..0e091b2 100644 --- a/services/mif_processor.py +++ b/services/mif_processor.py @@ -38,7 +38,7 @@ def build_coord_rows(contours: list, method: str, mt) -> list: или None — пустой разделитель между контурами. Правила: - - Первая координата MIF → X (колонка C), вторая → Y (D). + - Первая координата MIF → Y (колонка D), вторая → X (C). - Все точки нумеруются подряд по всем контурам. - Последняя (замыкающая) точка контура получает номер первой точки этого контура. """ @@ -49,11 +49,24 @@ def build_coord_rows(contours: list, method: str, mt) -> list: rows.append(None) if not contour: continue - first_num = global_num - for mx, my in contour[:-1]: + + # Single-point contour — добавляем одну строку + if len(contour) == 1: + my, mx = contour[0] # MIF: первая=Y(восток), вторая=X(север) rows.append((global_num, f"{mx:.2f}", f"{my:.2f}", method, mt)) global_num += 1 + continue + + # Для многоточечных контуров: нумеруем все точки, кроме последней, + # затем добавляем завершающую точку, которой присваивается номер + # первой точки контура (замыкание). + first_num = global_num + for my, mx in contour[:-1]: # MIF: первая=Y(восток), вторая=X(север) + rows.append((global_num, f"{mx:.2f}", f"{my:.2f}", method, mt)) + global_num += 1 + if len(contour) >= 2: - mx, my = contour[-1] + my, mx = contour[-1] # MIF: первая=Y(восток), вторая=X(север) rows.append((first_num, f"{mx:.2f}", f"{my:.2f}", method, mt)) + return rows