import io import time from typing import Iterable, Sequence import pandas as pd def write_dfs_to_excel( dfs: Sequence[pd.DataFrame], sheet_names: Sequence[str], index: bool = True, profile: dict | None = None, ) -> bytes: """Simple Excel export for Panel. Writes the given DataFrames to an in-memory XLSX file and returns the bytes. No Streamlit dependency and no heavy formatting, to keep Panel exports fast and avoid Streamlit runtime warnings. """ bytes_io = io.BytesIO() t0 = time.perf_counter() if profile is not None else 0.0 with pd.ExcelWriter(bytes_io, engine="xlsxwriter") as writer: for df, name in zip(dfs, sheet_names): # Ensure we always write a valid DataFrame, even if None was passed safe_df = df if isinstance(df, pd.DataFrame) else pd.DataFrame() t_sheet0 = time.perf_counter() if profile is not None else 0.0 safe_df.to_excel(writer, sheet_name=str(name), index=index) t_sheet1 = time.perf_counter() if profile is not None else 0.0 if profile is not None: sheets = profile.get("excel_sheets") if not isinstance(sheets, list): sheets = [] profile["excel_sheets"] = sheets try: rows = int(len(safe_df)) except Exception: # noqa: BLE001 rows = 0 try: cols = int(safe_df.shape[1]) except Exception: # noqa: BLE001 cols = 0 sheets.append( { "name": str(name), "rows": rows, "cols": cols, "seconds": float(t_sheet1 - t_sheet0), } ) if profile is not None: profile["excel_total_seconds"] = float(time.perf_counter() - t0) return bytes_io.getvalue()