Writing an Excel file with pandas exports a DataFrame into an .xlsx workbook that spreadsheet users can open without an import wizard. The export choices decide the worksheet name, row index handling, column order, blank cells, and header behavior that the receiving workbook will show.
DataFrame.to_excel() writes a table to one worksheet when it receives a path and a sheet name. A single-sheet export is enough when one DataFrame is the handoff, while ExcelWriter is the better fit when several sheets need to be written into one workbook.
The output path should be treated as a new handoff file because write mode replaces an existing workbook at the same path. Keep a copy of any workbook that must be preserved, then verify the sheet names, header row, filter, and read-back row count before sending the file onward.
Related: How to write a CSV file with pandas
Related: How to read an Excel file with pandas
Related: How to create a pandas DataFrame
from pathlib import Path import pandas as pd output = Path("exports/orders.xlsx") output.parent.mkdir(parents=True, exist_ok=True) orders = pd.DataFrame( { "order_id": pd.Series(["A100", "A101", "A102"], dtype="string"), "customer": ["Ada Lovelace", "Lin Chen", "Maya Patel"], "region": ["EMEA", "APAC", "AMER"], "total_usd": [149.5, None, 212.0], "ordered_at": pd.to_datetime( ["2026-06-01", "2026-06-02", "2026-06-03"] ), "internal_note": ["priority", "review", "standard"], } ) export_columns = ["order_id", "customer", "region", "total_usd", "ordered_at"] orders.to_excel( output, sheet_name="Orders", columns=export_columns, index=False, na_rep="", float_format="%.2f", freeze_panes=(1, 0), autofilter=True, engine="openpyxl", ) print(f"Wrote {output}") print("Sheet: Orders") print(f"Rows: {len(orders)}") print(f"Columns: {', '.join(export_columns)}")
columns excludes internal_note from the workbook, index=False keeps row labels out of the worksheet, and engine=“openpyxl” uses the openpyxl writer for .xlsx output.
$ python3 write_orders_excel.py Wrote exports/orders.xlsx Sheet: Orders Rows: 3 Columns: order_id, customer, region, total_usd, ordered_at
$ python3 - <<'PY'
from openpyxl import load_workbook
workbook = load_workbook("exports/orders.xlsx", data_only=True)
worksheet = workbook["Orders"]
headers = [cell.value for cell in worksheet[1]]
rows = list(worksheet.iter_rows(min_row=2, values_only=True))
print(workbook.sheetnames)
print(f"Worksheet rows: {len(rows)}")
print(f"Worksheet columns: {len(headers)}")
print(f"Headers: {headers}")
print(f"Freeze panes: {worksheet.freeze_panes}")
print(f"Auto filter: {worksheet.auto_filter.ref}")
PY
['Orders']
Worksheet rows: 3
Worksheet columns: 5
Headers: ['order_id', 'customer', 'region', 'total_usd', 'ordered_at']
Freeze panes: A2
Auto filter: A1:E4
The workbook should contain the intended sheet, exported headers, frozen header row, and filter range.
Tool: XLSX to CSV Converter
$ python3 - <<'PY'
import pandas as pd
round_trip = pd.read_excel(
"exports/orders.xlsx",
sheet_name="Orders",
dtype={"order_id": "string"},
parse_dates=["ordered_at"],
)
print(round_trip.to_string(index=False))
print()
print(f"Rows: {len(round_trip)}")
print(f"Columns: {', '.join(round_trip.columns)}")
print(f"Missing totals: {round_trip['total_usd'].isna().sum()}")
PY
order_id customer region total_usd ordered_at
A100 Ada Lovelace EMEA 149.5 2026-06-01
A101 Lin Chen APAC NaN 2026-06-02
A102 Maya Patel AMER 212.0 2026-06-03
Rows: 3
Columns: order_id, customer, region, total_usd, ordered_at
Missing totals: 1
The read-back output should show three rows, five exported columns, parsed dates, and one blank total from the source DataFrame.
Related: How to read an Excel file with pandas
$ rm -r write_orders_excel.py exports