Spaces:
Sleeping
Sleeping
| """Generate a real .xlsx file from the Excel artifact JSON.""" | |
| import io | |
| from typing import Any | |
| import xlsxwriter | |
| def _get_cell_value(cell_data, columns: list[str], col_idx: int) -> Any: | |
| """Extract display value from a cell (handles both raw values and cell objects).""" | |
| if cell_data is None: | |
| return "" | |
| if isinstance(cell_data, dict): | |
| return cell_data.get("value", cell_data.get("formula", "")) | |
| return cell_data | |
| def _get_cell_format(cell_data) -> dict | None: | |
| """Get xlsxwriter format options from cell object.""" | |
| if not isinstance(cell_data, dict): | |
| return None | |
| opts = {} | |
| if cell_data.get("bold"): | |
| opts["bold"] = True | |
| if cell_data.get("italic"): | |
| opts["italic"] = True | |
| if cell_data.get("format") == "currency": | |
| opts["num_format"] = "$#,##0.00" | |
| elif cell_data.get("format") == "percent": | |
| opts["num_format"] = "0.0%" | |
| elif cell_data.get("format") == "number": | |
| opts["num_format"] = "#,##0.00" | |
| return opts if opts else None | |
| def _row_to_list(row_data, columns: list[str]) -> tuple[list[Any], list[dict | None]]: | |
| """Convert a row (array or dict) to (values, formats) for writing.""" | |
| values = [] | |
| formats = [] | |
| if isinstance(row_data, list): | |
| for i, cell in enumerate(row_data): | |
| values.append(_get_cell_value(cell, columns, i)) | |
| formats.append(_get_cell_format(cell) if isinstance(cell, dict) else None) | |
| else: | |
| for i, col in enumerate(columns): | |
| cell = row_data.get(col, row_data.get(i, "")) | |
| values.append(_get_cell_value(cell, columns, i)) | |
| formats.append(_get_cell_format(cell) if isinstance(cell, dict) else None) | |
| return values, formats | |
| def generate_xlsx(artifact: dict[str, Any]) -> bytes: | |
| """Return the bytes of a .xlsx file generated from the artifact JSON.""" | |
| buffer = io.BytesIO() | |
| workbook = xlsxwriter.Workbook(buffer, {"in_memory": True}) | |
| sheets_data = artifact.get("sheets", []) | |
| if not sheets_data: | |
| ws = workbook.add_worksheet("Sheet1") | |
| ws.write(0, 0, "No data") | |
| workbook.close() | |
| buffer.seek(0) | |
| return buffer.getvalue() | |
| for sheet_data in sheets_data: | |
| name = (sheet_data.get("name") or "Sheet").replace("/", "-")[:31] | |
| columns = sheet_data.get("columns", []) | |
| rows = sheet_data.get("rows", []) | |
| ws = workbook.add_worksheet(name) | |
| # Header row | |
| for ci, col in enumerate(columns): | |
| ws.write(0, ci, str(col), workbook.add_format({"bold": True})) | |
| # Data rows | |
| for ri, row_data in enumerate(rows): | |
| values, formats = _row_to_list(row_data, columns) | |
| for ci, (val, fmt) in enumerate(zip(values, formats)): | |
| if fmt: | |
| cell_fmt = workbook.add_format(fmt) | |
| ws.write(ri + 1, ci, val, cell_fmt) | |
| else: | |
| ws.write(ri + 1, ci, val) | |
| workbook.close() | |
| buffer.seek(0) | |
| return buffer.getvalue() | |