|
|
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): |
|
|
|
|
|
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: |
|
|
rows = 0 |
|
|
try: |
|
|
cols = int(safe_df.shape[1]) |
|
|
except Exception: |
|
|
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() |
|
|
|