Q&A library Python

How do I write multiple sheets to one Excel file with pandas?

Python Advanced excelexcelwriterio

Short answer

Use pd.ExcelWriter as a context manager and call to_excel once per sheet with a different sheet_name. Writing each frame to a separate file, or reopening the writer, are the mistakes that lose sheets.

The short version

Open a pd.ExcelWriter as a context manager and call to_excel once per sheet, giving each a different sheet_name. All the frames land in one workbook, saved when the with block ends. The usual mistakes are writing each frame to a separate file, or opening the writer without a context manager and forgetting to save.

The correct pattern

import pandas as pd

q1 = pd.DataFrame({"city": ["Leeds"], "sales": [100]})
q2 = pd.DataFrame({"city": ["Bath"], "sales": [80]})

with pd.ExcelWriter("report.xlsx") as writer:
    q1.to_excel(writer, sheet_name="Q1", index=False)
    q2.to_excel(writer, sheet_name="Q2", index=False)

Each to_excel writes to the same writer, so both sheets end up in report.xlsx. The with block saves and closes the file automatically at the end.

The mistake that loses sheets

Calling to_excel on a filename repeatedly does not add sheets; each call overwrites the whole file, so only the last survives.

# WRONG: the second call overwrites the first
q1.to_excel("report.xlsx", sheet_name="Q1")
q2.to_excel("report.xlsx", sheet_name="Q2")   # report.xlsx now has only Q2

The shared ExcelWriter is what keeps the sheets together, because both writes target the same open workbook.

Turning off the index

Set index=False unless the DataFrame's index is meaningful, or you get an extra unlabelled column of row numbers in the sheet. This is the same habit as with CSV output.

Writing a dictionary of frames

If you have a dictionary mapping sheet names to DataFrames, loop over it.

sheets = {"Q1": q1, "Q2": q2}
with pd.ExcelWriter("report.xlsx") as writer:
    for name, frame in sheets.items():
        frame.to_excel(writer, sheet_name=name, index=False)

This scales to any number of sheets without repeating the write call by hand.

Positioning frames on a sheet

You can place several frames on the same sheet by setting startrow or startcol, which is useful for building a small report with a few tables stacked or side by side.

q1.to_excel(writer, sheet_name="summary", startrow=0, index=False)
q2.to_excel(writer, sheet_name="summary", startrow=len(q1) + 2, index=False)

Leaving a gap row between them keeps the tables visually separate.

The engine

Writing .xlsx uses the openpyxl engine, which pandas selects automatically if it is installed. If you get an error about a missing engine, install openpyxl. For appending to an existing workbook rather than replacing it, pass mode="a" and choose how existing sheets are handled with if_sheet_exists, though creating the file fresh is simpler when you can.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project