web_aku / backend /services /data_loader.py
ikhsanmlnn's picture
first commit
2c38fa9
Raw
History Blame Contribute Delete
2.22 kB
from __future__ import annotations
from pathlib import Path
from functools import lru_cache
from typing import List, Dict, Any, Optional
from openpyxl import load_workbook
ROOT = Path(__file__).resolve().parents[2]
BACKEND_DIR = Path(__file__).resolve().parents[1]
DATA_DIR = BACKEND_DIR / "data"
DATA_DIR.mkdir(exist_ok=True)
def _excel_path(filename: str) -> Path:
# Mencari file Excel di root repo
p = ROOT / filename
if not p.exists():
# Coba juga di dalam folder backend/data jika sudah diekspor
q = DATA_DIR / filename
if q.exists():
return q
return p
def _sheet_to_records(ws) -> List[Dict[str, Any]]:
rows = list(ws.iter_rows(values_only=True))
if not rows:
return []
headers = [str(h).strip() if h is not None else "" for h in rows[0]]
out: List[Dict[str, Any]] = []
for r in rows[1:]:
item = {}
for i, h in enumerate(headers):
# openpyxl already returns Python primitives
item[h or f"col_{i}"] = r[i] if i < len(r) else None
out.append(item)
return out
@lru_cache(maxsize=16)
def load_excel_as_records(filename: str, sheet_name: Optional[str] = None) -> List[Dict[str, Any]]:
path = _excel_path(filename)
if not path.exists():
raise FileNotFoundError(f"File tidak ditemukan: {path}")
wb = load_workbook(filename=str(path), read_only=True, data_only=True)
if sheet_name is None:
ws = wb[wb.sheetnames[0]]
return _sheet_to_records(ws)
else:
if sheet_name in wb.sheetnames:
ws = wb[sheet_name]
return _sheet_to_records(ws)
# jika nama sheet tidak ada, gabungkan semua
records: List[Dict[str, Any]] = []
for name in wb.sheetnames:
records.extend(_sheet_to_records(wb[name]))
return records
def export_excel_to_json(filename: str, out_json: Path, sheet_name: Optional[str] = None) -> Path:
records = load_excel_as_records(filename, sheet_name)
out_json.parent.mkdir(parents=True, exist_ok=True)
import json
with out_json.open("w", encoding="utf-8") as f:
json.dump(records, f, ensure_ascii=False, indent=2)
return out_json