Skip to content
Snippets Groups Projects

Filling XLSX: Everything except multiple choice.

Merged Daniel Hornung requested to merge f-json-table into dev
All threads resolved!
Compare and Show latest version
10 files
+ 259
22
Compare changes
  • Side-by-side
  • Inline
Files
10
@@ -23,12 +23,14 @@
from __future__ import annotations
import json
import pathlib
from collections import OrderedDict
from types import SimpleNamespace
from typing import Any, Dict, List, Optional, Union, TextIO
from typing import Any, Dict, List, Optional, TextIO, Union
from jsonschema import FormatChecker, validate
from openpyxl import load_workbook, Workbook
from jsonschema.exceptions import ValidationError
from openpyxl import Workbook, load_workbook
from openpyxl.worksheet.worksheet import Worksheet
from .table_generator import ColumnType, RowType
@@ -182,10 +184,19 @@ class TemplateFiller:
self._props[fullpath] = value
def fill_from_data(self, data: Dict[str, Any]):
# TODO recursive for dicts and list?
"""Fill current level with all scalar elements of ``data``."""
for name, value in data.items():
if not isinstance(value, (dict, list)):
self[name] = value
elif isinstance(value, dict):
if not value or isinstance(list(value.items())[0], list):
continue
old_path = self._current_path
new_path = self._current_path.copy() + [name]
self._current_path = new_path
self.fill_from_data(data=value)
self._current_path = old_path
def _create_index(self):
"""Create a sheet index for the workbook.
@@ -263,6 +274,9 @@ out: union[dict, None]
insertables: Dict[str, Any] = {}
for name, content in data.items():
# TODO is this the best way to do it????
if name == "file":
continue
path = current_path + [name]
next_context = context.next_level(name)
# preprocessing
@@ -319,7 +333,11 @@ out: union[dict, None]
# Insert foreign keys
if insert_row is not None and sheet is not None and _is_exploded_sheet(sheet):
foreigns = _get_foreign_key_columns(sheet)
try:
foreigns = _get_foreign_key_columns(sheet)
except ValueError:
print(f"Sheet: {sheet}")
raise
for index, path in ((f.index, f.path) for f in foreigns.values()):
value = context[path]
sheet.cell(row=insert_row+1, column=index+1, value=value)
@@ -352,10 +370,17 @@ validation_schema: dict, optional
# Validation
if validation_schema is not None:
validation_schema = _read_or_dict(validation_schema)
validate(data, validation_schema, format_checker=FormatChecker())
try:
validate(data, validation_schema, format_checker=FormatChecker())
except ValidationError as ve:
print(ve.message)
raise RuntimeError("Validation failed")
# Filling the data
result_wb = load_workbook(template)
template_filler = TemplateFiller(result_wb)
template_filler.fill_data(data=data)
parentpath = pathlib.Path(result).parent
parentpath.mkdir(parents=True, exist_ok=True)
result_wb.save(result)
Loading