API Reference

This page provides detailed API documentation for SerializableExcel.

ExcelModel

Base class for all Excel-serializable models. Inherit from this class to create your models.

Methods

class ExcelModel

Base class for Excel-serializable Pydantic models.

from_excel(source: str | bytes | BytesIO, dynamic_columns: bool = False) List[ExcelModel]

Read models from an Excel file, bytes, or BytesIO.

Parameters:
  • source (Union[str, bytes, BytesIO]) – Path to the Excel file (.xlsx), bytes, or BytesIO object

  • dynamic_columns (bool) – Enable detection of additional columns not defined in model

Returns:

List of model instances

Return type:

List[ExcelModel]

Raises:

Example:

# From file
users = UserModel.from_excel("users.xlsx")
forecasts = ForecastModel.from_excel("forecasts.xlsx", dynamic_columns=True)

# From bytes (e.g., from API request)
file_bytes = request.files['file'].read()
users = UserModel.from_excel(file_bytes)

# From BytesIO
from io import BytesIO
stream = BytesIO(uploaded_file.read())
users = UserModel.from_excel(stream)
to_excel(instances: List[ExcelModel], file_path: str | None = None, return_bytes: bool = False, column_order: Callable[[str], int | None] | Dict[str, int] | None = None, dynamic_column_order: Callable[[Dict[str, int]], Dict[str, int]] | None = None) bytes | None

Export model instances to an Excel file or return as bytes.

Parameters:
  • instances (List[ExcelModel]) – List of model instances to export

  • file_path (Optional[str]) – Path where to save the Excel file (.xlsx). Required if return_bytes=False.

  • return_bytes (bool) – If True, return Excel content as bytes instead of saving to file

  • column_order (Optional[Union[Callable[[str], Optional[int]], Dict[str, int]]]) – Optional function or dict to specify order for static columns. If function: takes header name (str) and returns order number (int) or None. If dict: maps header names to order numbers.

  • dynamic_column_order (Optional[Callable[[Dict[str, int]], Dict[str, int]]]) – Optional function to specify order for dynamic columns. Takes dict {title: order} and returns normalized dict {title: normalized_order}. The function should normalize orders (remove gaps, make sequential).

Returns:

bytes if return_bytes=True, None otherwise

Return type:

Optional[bytes]

Raises:
  • ValueError – If instances list is empty or invalid

  • ValueError – If file_path is not provided when return_bytes=False

Example:

# Save to file
users = [UserModel(name="Alice", age=30)]
UserModel.to_excel(users, "output.xlsx")

# Return bytes for API response
excel_bytes = UserModel.to_excel(users, return_bytes=True)

# Use with FastAPI/Starlette
from io import BytesIO
from starlette.responses import StreamingResponse
return StreamingResponse(
    BytesIO(excel_bytes),
    media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    headers={"Content-Disposition": "attachment; filename=users.xlsx"}
)

# With column ordering
def static_order(header: str) -> Optional[int]:
    order_map = {"Email": 1, "Name": 2, "Age": 3}
    return order_map.get(header)

def dynamic_order(orders: Dict[str, int]) -> Dict[str, int]:
    sorted_items = sorted(orders.items(), key=lambda x: x[1])
    return {title: idx + 1 for idx, (title, _) in enumerate(sorted_items)}

UserModel.to_excel(
    users,
    "output.xlsx",
    column_order=static_order,
    dynamic_column_order=dynamic_order
)

Column

Descriptor for defining static columns in models.

class Column

Descriptor for defining static columns in ExcelModel classes.

__init__(header: str, validator: Callable | None = None, getter: Callable | None = None, getter_cell_color: Callable | None = None, default: Any = None, required: bool = False)

Initialize a Column descriptor.

Parameters:
  • header (str) – Excel column header name (required)

  • validator (Optional[Callable[[Any], Any]]) – Function to validate/transform value when reading from Excel. Should accept the value and return the validated/transformed value.

  • getter (Optional[Callable[[Any], Any]]) – Function to extract value from model when writing to Excel. Should accept the model instance and return the value.

  • getter_cell_color (Optional[Callable[[Any, Dict[str, Any], str, int], Optional[CellStyle]]]) – Function to determine cell style when writing to Excel. Signature: (cell_value, row_data, column_name, row_index) -> Optional[CellStyle]

  • default (Any) – Default value if cell is empty

  • required (bool) – Raise error if value is missing

Example:

from serializable_excel import ExcelModel, Column, CellStyle, Colors

def highlight_age(cell_value, row_data, column_name, row_index):
    if cell_value and cell_value > 30:
        return CellStyle(fill_color=Colors.WARNING)
    return CellStyle(fill_color=Colors.UNCHANGED)

class UserModel(ExcelModel):
    name: str = Column(header="Name", required=True)
    age: int = Column(header="Age", validator=int, default=0, getter_cell_color=highlight_age)
    email: str = Column(header="Email", validator=validate_email)

DynamicColumn

Descriptor for defining dynamic columns that are detected at runtime.

class DynamicColumn

Descriptor for defining dynamic columns that are detected at runtime in Excel files.

__init__(getter: Callable[[Any], Dict[str, Any]] | None = None, validator: Callable[[str, str], Any] | None = None, validators: Dict[str, Callable] | None = None, getter_cell_color: Callable | None = None, getters_cell_color: Dict[str, Callable] | None = None, type_getter: Callable[[str], ExcelType | None] | None = None)

Initialize a DynamicColumn descriptor.

Parameters:
  • getter (Optional[Callable[[Any], Dict[str, Any]]]) – Function to extract dynamic values when exporting to Excel. Should accept the model instance and return a dict[str, Any] of column names to values.

  • validator (Optional[Callable[[str, str], Any]]) – Function to validate all dynamic columns. Receives (column_name: str, value: str) and returns validated value.

  • validators (Optional[Dict[str, Callable[[str, str], Any]]]) – Dictionary mapping column names to validator functions. Each validator receives (column_name: str, value: str) and returns validated value.

  • getter_cell_color (Optional[Callable[[Any, Dict[str, Any], str, int], Optional[CellStyle]]]) – Function to determine cell style for all dynamic columns. Signature: (cell_value, row_data, column_name, row_index) -> Optional[CellStyle]

  • getters_cell_color (Optional[Dict[str, Callable[[Any, Dict[str, Any], str, int], Optional[CellStyle]]]]) – Dictionary mapping column names to style getter functions. Each function has same signature as getter_cell_color.

  • type_getter – Function to determine Excel type for dynamic columns. Signature: (column_name: str) -> Optional[ExcelType].

CellStyle and Colors

class CellStyle

Represents cell styling options for Excel cells.

fill_color

Background color in HEX format (e.g., “FF0000” for red)

font_color

Font color in HEX format

font_bold

Whether the font should be bold

font_italic

Whether the font should be italic

Example:

from serializable_excel import CellStyle, Colors

style = CellStyle(
    fill_color=Colors.CHANGED,
    font_color=Colors.FONT_BLACK,
    font_bold=True
)
class Colors

Predefined color constants for common use cases.

Background colors:

  • CHANGED - Yellow (#FFFF00) - for changed values

  • UNCHANGED - Light green (#90EE90) - for unchanged values

  • ERROR - Light red (#FF6B6B) - for errors

  • WARNING - Orange (#FFA500) - for warnings

  • INFO - Light blue (#87CEEB) - for information

  • NEW - Pale green (#98FB98) - for new entries

Font colors:

  • FONT_RED - Red (#FF0000)

  • FONT_GREEN - Green (#008000)

  • FONT_BLUE - Blue (#0000FF)

  • FONT_BLACK - Black (#000000)

  • FONT_GRAY - Gray (#808080)

Exceptions

exception ExcelModelError

Base exception for all SerializableExcel errors.

exception ValidationError

Raised when data validation fails during from_excel().

Inherits from ValueError.

exception ColumnNotFoundError

Raised when a required column is not found in the Excel file.

Inherits from ExcelModelError.

Type Hints

For better IDE support and type checking, SerializableExcel provides type hints:

from typing import List
from serializable_excel import ExcelModel, Column

class UserModel(ExcelModel):
    name: str = Column(header="Name")
    age: int = Column(header="Age")

# Type hints work correctly
users: List[UserModel] = UserModel.from_excel("users.xlsx")