Skip to content

Excel Writer

excel_model.excel_writer

Orchestrator: build_workbook() — creates the full Excel workbook.

build_workbook(spec, inputs, output_path, style)

Build and save a complete Excel workbook from the model spec.

Creates Assumptions, Inputs, and Model sheets. Dispatches to the appropriate model builder based on spec.model_type.

Source code in excel_model/excel_writer.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def build_workbook(
    spec: ModelSpec,
    inputs: InputData | None,
    output_path: str,
    style: StyleConfig,
) -> None:
    """Build and save a complete Excel workbook from the model spec.

    Creates Assumptions, Inputs, and Model sheets.
    Dispatches to the appropriate model builder based on spec.model_type.
    """
    wb = Workbook()
    # Remove default sheet
    if "Sheet" in wb.sheetnames:
        del wb["Sheet"]

    if spec.model_type == "comparison":
        # Comparison models don't use time_engine periods
        from excel_model.models.comparison import build_comparison

        build_comparison(wb, spec, inputs, style)
    else:
        periods = generate_periods(
            start_period=spec.start_period,
            n_periods=spec.n_periods,
            n_history=spec.n_history_periods,
            granularity=spec.granularity,
        )

        if spec.model_type == "p_and_l":
            from excel_model.models.p_and_l import build_p_and_l

            build_p_and_l(wb, spec, inputs, style, periods)

        elif spec.model_type == "dcf":
            from excel_model.models.dcf import build_dcf

            build_dcf(wb, spec, inputs, style, periods)

        elif spec.model_type == "budget_vs_actuals":
            from excel_model.models.budget_vs_actuals import build_budget_vs_actuals

            build_budget_vs_actuals(wb, spec, inputs, style, periods)

        elif spec.model_type == "scenario":
            from excel_model.models.scenario import build_scenario

            build_scenario(wb, spec, inputs, style, periods)

        elif spec.model_type == "custom":
            from excel_model.models.p_and_l import build_p_and_l

            build_p_and_l(wb, spec, inputs, style, periods)

        else:
            raise ValueError(f"Unknown model_type: {spec.model_type!r}")

    out = Path(output_path)
    out.parent.mkdir(parents=True, exist_ok=True)
    wb.save(str(out))