feat: Excel-Import glätten und Dokumentlistenaktionen korrigieren

This commit is contained in:
2026-07-22 14:34:14 +02:00
parent 6df5c101c5
commit eb503df94b
11 changed files with 129 additions and 36 deletions
+26 -13
View File
@@ -29,14 +29,14 @@ class ExcelSheetResult:
images: list[ImportedImage] = field(default_factory=list)
def import_document(upload) -> ImportResult:
def import_document(upload, flatten_excel=False) -> ImportResult:
suffix = Path(upload.name).suffix.lower()
content = upload.read()
upload.seek(0)
if suffix == ".docx":
return _docx(content)
if suffix in {".xlsx", ".xlsm"}:
return _xlsx(content)
return _xlsx(content, flatten=flatten_excel)
if suffix == ".pdf":
return _pdf(content)
if suffix in {".md", ".txt"}:
@@ -53,9 +53,28 @@ def _docx(content):
return ImportResult(result.value.strip(), warnings)
def _xlsx(content):
from openpyxl import load_workbook
def _render_excel_rows(rows, flatten=False):
from tabulate import tabulate
width = max(len(row) for row in rows)
rows = [row + [""] * (width - len(row)) for row in rows]
header, body = rows[0], rows[1:]
if not flatten:
return tabulate(body, headers=header, tablefmt="github")
blocks = []
for number, row in enumerate(body, 1):
values = []
for column, value in zip(header, row):
if value == "":
continue
label = column or "Feld"
values.append(f"**{label}:** {value}")
if values:
blocks.append(f"### Datensatz {number}\n\n" + " \n".join(values))
return "\n\n".join(blocks) or "_Keine Datensätze_"
def _xlsx(content, flatten=False):
from openpyxl import load_workbook
workbook = load_workbook(BytesIO(content), read_only=True, data_only=True)
sections = []
for sheet in workbook.worksheets:
@@ -64,20 +83,16 @@ def _xlsx(content):
rows.pop()
if not rows:
continue
width = max(len(row) for row in rows)
rows = [row + [""] * (width - len(row)) for row in rows]
header, body = rows[0], rows[1:]
sections.append(f"## {sheet.title}\n\n{tabulate(body, headers=header, tablefmt='github')}")
sections.append(f"## {sheet.title}\n\n{_render_excel_rows(rows, flatten)}")
if not sections:
raise ImportFailure("Die Arbeitsmappe enthält keine Daten.")
return ImportResult("\n\n".join(sections))
def import_excel_sheets(upload) -> list[ExcelSheetResult]:
def import_excel_sheets(upload, flatten=False) -> list[ExcelSheetResult]:
"""Convert each non-empty worksheet into an individual document payload."""
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from tabulate import tabulate
suffix = Path(upload.name).suffix.lower()
if suffix not in {".xlsx", ".xlsm"}:
@@ -111,9 +126,7 @@ def import_excel_sheets(upload) -> list[ExcelSheetResult]:
if not rows and not images:
continue
if rows:
width = max(len(row) for row in rows)
rows = [row + [""] * (width - len(row)) for row in rows]
markdown = tabulate(rows[1:], headers=rows[0], tablefmt="github")
markdown = _render_excel_rows(rows, flatten)
else:
markdown = ""
results.append(ExcelSheetResult(title=sheet.title, markdown=markdown, images=images))