# How to Append a DataFrame to an Existing Excel File Using pandas to_excel

> Learn to append a DataFrame to an existing Excel file with pandas to_excel. Master `mode="a"` and `if_sheet_exists` for seamless data integration. Maximize your Excel workflow today.

- Repository: [pandas/pandas](https://github.com/pandas-dev/pandas)
- Tags: how-to-guide
- Published: 2026-02-15

---

**Use `mode="a"` in `DataFrame.to_excel()` to open an existing workbook in append mode, and set `if_sheet_exists` to `"new"`, `"overlay"`, or `"replace"` to control how pandas handles sheet name conflicts.**

The pandas library provides robust Excel I/O capabilities through the `ExcelWriter` class, enabling you to append DataFrames to existing workbooks without overwriting previous data. According to the pandas-dev/pandas source code, the `to_excel` method defined in [`pandas/core/generic.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/core/generic.py) delegates to this writer architecture, supporting append operations via the `mode` parameter. This article explains how to use pandas to_excel append functionality to add new sheets or overlay data onto existing sheets.

## Understanding the pandas Excel Architecture

Pandas implements Excel operations through a layered architecture centered on the `ExcelWriter` context manager. When you call `DataFrame.to_excel`, the method defined in [`pandas/core/generic.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/core/generic.py) (around line 2140) constructs an `ExcelWriter` instance or reuses one passed by the user.

The core logic for handling file modes and sheet existence resides in [`pandas/io/excel/_base.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/io/excel/_base.py) (around line 1275). This `ExcelWriter` class manages the backend engines—such as **openpyxl**, **xlsxwriter**, or **odf**—that perform the actual workbook manipulation. When you specify `mode="a"`, the writer loads the existing workbook into memory before applying your changes.

## How to Append Data Using pandas to_excel

### Adding a New Sheet to an Existing Workbook

The simplest append operation creates a new sheet within an existing file. Set `mode="a"` to open the workbook in append mode and provide a unique `sheet_name`:

```python
import pandas as pd

new_data = pd.DataFrame({
    "Product": ["Widget A", "Widget B"],
    "Revenue": [1200, 850]
})

# Append as a new sheet named "Q2"

new_data.to_excel(
    "sales_report.xlsx",
    sheet_name="Q2",
    index=False,
    mode="a"
)

```

By default, `if_sheet_exists` behaves as `"new"`, raising an error if the sheet already exists. This protects against accidental overwrites when appending.

### Overlaying Data onto an Existing Sheet

To append rows to an existing sheet without deleting its current content, use `if_sheet_exists="overlay"` combined with `startrow` calculations. First, read the existing data to determine the next empty row:

```python

# Read existing sheet to find the starting row

existing = pd.read_excel("sales_report.xlsx", sheet_name="Q1")
start_row = len(existing) + 2  # +1 for header, +1 for blank row

new_data.to_excel(
    "sales_report.xlsx",
    sheet_name="Q1",
    startrow=start_row,
    index=False,
    header=False,  # Omit headers when appending rows

    mode="a",
    if_sheet_exists="overlay"
)

```

The `overlay` mode writes data starting at the specified `startrow` and `startcol` without clearing existing cells, making it ideal for cumulative reporting.

### Replacing an Existing Sheet

When you need to refresh a sheet with new data while preserving other sheets in the workbook, use `if_sheet_exists="replace"`:

```python
new_data.to_excel(
    "sales_report.xlsx",
    sheet_name="Q1",
    index=False,
    mode="a",
    if_sheet_exists="replace"
)

```

This deletes the existing "Q1" sheet and creates a new one with the current DataFrame content, leaving all other sheets in `sales_report.xlsx` intact.

## Critical Parameters for Excel Appending

Understanding these parameters ensures reliable append operations:

- **`mode`**: Accepts `"w"` (write, default) or `"a"` (append). Use `"a"` to open existing files without truncation.
- **`if_sheet_exists`**: Required when `mode="a"` and the sheet exists. Options include:
  - `"new"`: Raise `ValueError` if sheet exists (safest default).
  - `"overlay"`: Write into existing sheet at specified coordinates.
  - `"replace"`: Delete and recreate the sheet.
- **`startrow` / `startcol`**: Zero-indexed offsets for writing data. Essential for `overlay` mode to position new data below existing rows.
- **`header`**: Boolean indicating whether to write column headers. Set `False` when appending rows to existing sheets to avoid duplicate headers.
- **`engine`**: Explicitly select `"openpyxl"`, `"xlsxwriter"`, or other backends. Openpyxl is required for `mode="a"` operations on `.xlsx` files.

## Summary

- Use `mode="a"` in `DataFrame.to_excel()` to open existing Excel files for appending instead of overwriting.
- Control sheet collision behavior with `if_sheet_exists`, choosing between `"new"` (error), `"overlay"` (merge), or `"replace"` (refresh).
- Calculate `startrow` based on existing data length when using `overlay` mode to append rows without overwriting.
- Set `header=False` when appending to existing sheets to prevent duplicate column headers.
- The underlying implementation resides in [`pandas/core/generic.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/core/generic.py) for the DataFrame method and [`pandas/io/excel/_base.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/io/excel/_base.py) for the `ExcelWriter` context manager.

## Frequently Asked Questions

### Can I append rows to an existing sheet without overwriting data?

Yes, use `if_sheet_exists="overlay"` combined with the `startrow` parameter. First read the existing sheet with `pd.read_excel()` to determine the length of existing data, then set `startrow` to that length plus an offset for headers. Set `header=False` to avoid rewriting column names. This writes the new DataFrame below existing rows without clearing the sheet.

### What is the difference between overlay and replace modes?

The `overlay` mode writes data starting at the specified `startrow` and `startcol` coordinates while preserving all other existing content in the sheet. The `replace` mode deletes the entire existing sheet and creates a new one with the provided name, effectively clearing all previous data in that specific sheet while leaving other sheets in the workbook untouched.

### Which Excel engine works best for appending data?

For `mode="a"` operations on `.xlsx` files, **openpyxl** is the recommended engine and is required for reading existing workbooks. The **xlsxwriter** engine does not support append mode because it cannot read existing files—it only creates new workbooks. Pandas automatically selects openpyxl for append operations on xlsx files, but you can explicitly specify `engine="openpyxl"` for clarity.

### Why does pandas raise an error when I use mode="a"?

If you receive a `ValueError` stating that the sheet already exists, you have encountered the default `if_sheet_exists="new"` behavior. When `mode="a"` is specified and the target sheet name already exists in the workbook, pandas requires you to explicitly state how to handle the conflict. You must provide `if_sheet_exists` with either `"overlay"`, `"replace"`, or `"new"` (which raises the error intentionally to prevent accidental overwrites).