> ## Documentation Index
> Fetch the complete documentation index at: https://jetxl.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Executive dashboard

> Combine a summary sheet with the detail sheets behind it

The pattern most requested for internal reporting: one clean summary that opens first, with the underlying detail on tabs behind it.

```python theme={null}
import os
import polars as pl
import jetxl as jet

summary = pl.DataFrame({
    "Quarter": ["Q1", "Q2", "Q3", "Q4"],
    "Revenue": [100000, 120000, 115000, 140000],
    "Target":  [95000, 110000, 120000, 135000],
})

detail = pl.DataFrame({
    "Date":    ["2026-01-05", "2026-01-12", "2026-01-19"],
    "Region":  ["North", "South", "East"],
    "Amount":  [12500.00, 8900.00, 21000.00],
})

sheets = [
    {
        "data": summary.to_arrow(),
        "name": "Summary",
        "styled_headers": True,
        "freeze_rows": 1,
        "auto_width": True,
        "gridlines_visible": False,
        "zoom_scale": 120,
        "tab_color": "0070C0",
        "default_row_height": 20.0,
        "column_formats": {"Revenue": "currency", "Target": "currency"},
        "charts": [{
            "chart_type": "column",
            "start_row": 1, "start_col": 0,
            "end_row": 1 + summary.height, "end_col": 2,
            "from_col": 4,  "from_row": 1,
            "to_col": 12,   "to_row": 18,
            "title": "Revenue vs Target",
            "title_bold": True,
            "title_font_size": 1600,
            "title_color": "0070C0",
            "category_col": 0,
            "x_axis_title": "Quarter",
            "y_axis_title": "Amount ($)",
            "legend_position": "bottom",
            "axis_min": 0.0,
        }],
    },
    {
        "data": detail.to_arrow(),
        "name": "Detail",
        "styled_headers": True,
        "freeze_rows": 1,
        "auto_filter": True,
        "auto_width": True,
        "tab_color": "00B050",
        "column_formats": {"Amount": "currency", "Date": "date"},
        "conditional_formats": [{
            "start_row": 2, "start_col": 2,
            "end_row": 1 + detail.height, "end_col": 2,
            "rule_type": "color_scale",
            "min_color": "F8696B",
            "mid_color": "FFEB84",
            "max_color": "63BE7B",
        }],
    },
]

jet.write_sheets_arrow(
    sheets,
    "dashboard.xlsx",
    num_threads=min(os.cpu_count() or 1, len(sheets)),
)
```

<Note>
  Verified against jetxl 0.3.1: this produces a two-tab workbook, Summary then Detail, that opens cleanly.
</Note>

## What makes it read as a dashboard

<AccordionGroup>
  <Accordion title="Summary sheet comes first" icon="1">
    Sheet order follows list order, and Excel opens on the first tab. Put the answer there and the working behind it.
  </Accordion>

  <Accordion title="Gridlines off, zoom up" icon="display">
    Only on the summary. The detail sheet keeps its gridlines, because people scanning rows want them.
  </Accordion>

  <Accordion title="Tabs colored by role" icon="palette">
    Blue for the summary, green for detail. In a workbook of twelve tabs this is what makes it navigable.
  </Accordion>

  <Accordion title="Axis starts at zero" icon="chart-column">
    `axis_min` set to `0.0` on a column chart. Without it Excel may truncate the axis and exaggerate the gap between revenue and target.
  </Accordion>
</AccordionGroup>

<Tip>
  Every range here is computed from `summary.height` or `detail.height` rather than hardcoded, so the workbook survives a change in row count. Use `len(df)` with Pandas.
</Tip>
