@@ -0,0 +1,72 @@
|
||||
"""AgroStar xlsx (сводка проб) → AgrostarParseResult."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
from typing import Any
|
||||
|
||||
from openpyxl import load_workbook
|
||||
|
||||
from app.lab.etl.agrostar_tabular import map_tabular_label, sample_from_agro_fields, tabular_rows_to_agro_fields
|
||||
from app.lab.etl.agrostar_xml_import import AgrostarParseResult, _parse_float
|
||||
|
||||
|
||||
def parse_agrostar_xlsx(data: bytes) -> AgrostarParseResult:
|
||||
result = AgrostarParseResult(lab_name="АгроСтар")
|
||||
try:
|
||||
wb = load_workbook(io.BytesIO(data), data_only=True, read_only=False)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
result.errors.append(f"Не удалось открыть xlsx: {exc}")
|
||||
return result
|
||||
|
||||
ws = wb.active
|
||||
if ws.max_row < 4 or ws.max_column < 2:
|
||||
result.errors.append("Пустой или неузнаваемый xlsx")
|
||||
return result
|
||||
|
||||
sample_nos: list[str] = []
|
||||
farms: list[str] = []
|
||||
labels: list[str] = []
|
||||
for col in range(2, ws.max_column + 1):
|
||||
no = ws.cell(1, col).value
|
||||
if no is None:
|
||||
continue
|
||||
sample_nos.append(str(no).strip())
|
||||
farms.append(str(ws.cell(2, col).value or "").strip())
|
||||
labels.append(str(ws.cell(3, col).value or "").strip())
|
||||
|
||||
if not sample_nos:
|
||||
result.errors.append("В xlsx нет колонок с пробами")
|
||||
return result
|
||||
|
||||
row_values: list[tuple[str, list[str]]] = []
|
||||
for row in range(4, ws.max_row + 1):
|
||||
label = ws.cell(row, 1).value
|
||||
if label is None:
|
||||
continue
|
||||
label_str = str(label).strip()
|
||||
if not label_str or not map_tabular_label(label_str):
|
||||
continue
|
||||
vals = []
|
||||
for col in range(2, 2 + len(sample_nos)):
|
||||
raw = ws.cell(row, col).value
|
||||
vals.append("" if raw is None else str(raw))
|
||||
row_values.append((label_str, vals))
|
||||
|
||||
for idx, sample_no in enumerate(sample_nos):
|
||||
pairs = [(label, vals[idx]) for label, vals in row_values if idx < len(vals)]
|
||||
agro_fields = tabular_rows_to_agro_fields(pairs)
|
||||
if "DM" not in agro_fields:
|
||||
result.errors.append(f"Проба {sample_no}: нет СВ")
|
||||
continue
|
||||
sample = sample_from_agro_fields(
|
||||
sample_no=sample_no,
|
||||
farm_name=farms[idx] if idx < len(farms) else "",
|
||||
desc_1=labels[idx] if idx < len(labels) else sample_no,
|
||||
agro_fields=agro_fields,
|
||||
)
|
||||
result.samples.append(sample)
|
||||
|
||||
if not result.samples and not result.errors:
|
||||
result.errors.append("Не удалось разобрать пробы из xlsx")
|
||||
return result
|
||||
Reference in New Issue
Block a user