Как записать DataFrame в Excel: полное руководство с примерами на Python

Экспорт данных из DataFrame в Excel — одна из самых востребованных операций при работе с Pandas. Без этого навыка невозможно представить анализ данных: будь то отчёт для руководства, подготовка датасета для коллег или архивирование результатов расчётов. Однако даже опытные специалисты сталкиваются с нюансами: почему-то пропадают индексы, кириллица отображается кракозябрами, а файлы весят гигабайты при минимальном объёме данных.

В этой статье мы разберём все актуальные способы сохранения DataFrame в Excel, от базового to_excel() до продвинутых техник с XlsxWriter и OpenPyXL. Вы узнаете, как контролировать форматирование ячеек, оптимизировать размер файла и избегать типичных ошибок при работе с большими наборами данных. А ещё — сравним .xlsx и .csv по 5 ключевым критериям, чтобы вы могли выбрать оптимальный формат для своей задачи.

Если вы когда-нибудь получали от клиента вопрос "А почему в вашем файле вместо букв знаки вопроса?" или тратили часы на поиск причины, почему Excel не открывает экспортированную таблицу — эта инструкция поможет раз и навсегда закрыть эти проблемы. Мы не будем ограничиваться копированием документации, а покажем реальные кейсы с кодом, который можно скопировать и сразу использовать в своём проекте.

Особое внимание уделим трём критическим моментам, которые редко освещают в туториалах:

  1. Как сохранить несколько листов в одном файле Excel с разными DataFrame;
  2. Почему to_excel() может "съедать" память при работе с данными объёмом >100К строк;
  3. Скрытые настройки XlsxWriter, которые ускоряют экспорт в 2-3 раза.

Для примера возьмём типичный DataFrame с данными о продажах электроники — его структура поможет проиллюстрировать все нюансы форматирования (даты, валюта, проценты). Если у вас уже есть свой датасет — просто подставьте его вместо нашего в кодовых блоках.

1. Базовый экспорт DataFrame в Excel с Pandas

Начнём с самого простого: метода to_excel(), который встроен в каждый объект DataFrame. Этот способ подходит для 80% задач, когда нужно быстро сохранить данные без дополнительного форматирования.

Минимальный рабочий пример:

import pandas as pd

Создаём тестовый DataFrame

data = {

"Дата": ["2023-01-15", "2023-01-16", "2023-01-17"],

"Товар": ["Смартфон", "Ноутбук", "Планшет"],

"Продажи": [120, 45, 300],

"Цена": [29990, 89990, 15990]

}

df = pd.DataFrame(data)

Сохраняем в Excel

df.to_excel("продажи.xlsx", index=False)

Что здесь происходит:

  • 📁 Создаётся файл продажи.xlsx в текущей директории;
  • 📊 Данные записываются на первый лист (по умолчанию название "Sheet1");
  • 🔢 Параметр index=False убирает колонку с индексами (если не указать — появится лишний столбец с номерами строк).
⚠️ Внимание: Если в вашем DataFrame есть столбцы с датами (тип datetime64), Pandas по умолчанию сохранит их в формате YYYY-MM-DD HH:MM:SS. Чтобы Excel корректно распознал их как даты, потребуется дополнительная настройка — об этом в разделе про XlsxWriter.

Основные параметры метода to_excel(), которые пригодятся в 90% случаев:

Параметр Описание Пример значения
sheet_name Имя листа в Excel "Отчёт_январь"
startrow Номер строки, с которой начнётся запись (нумерация с 0) 2 (пропустит первые 2 строки)
header Записывать заголовки столбцов False (если нужно сохранить без шапки)
freeze_panes Закрепить области (например, шапку таблицы) (1, 0) (закрепит первую строку)

Пример с расширенными настройками:

df.to_excel(

"отчёт_по_продажам.xlsx",

sheet_name="Январь_2023",

startrow=1,

index=False,

freeze_panes=(1, 0) # Закрепляем шапку

)

📊 Какой формат вы чаще используете для экспорта данных?
Excel (.xlsx)
CSV (.csv)
JSON (.json)
SQL-дамп
Другой

2. Продвинутый экспорт с XlsxWriter: форматирование и производительность

Когда базового to_excel() недостаточно — на помощь приходит библиотека XlsxWriter. Она позволяет:

  • 🎨 Настраивать форматирование ячеек (цвета, шрифты, границы);
  • 📊 Добавлять формулы и условное форматирование;
  • ⚡ Ускорять запись больших DataFrame (до 100К+ строк).

Установите библиотеку, если ещё не сделали этого:

pip install xlsxwriter

Пример с настройкой формата даты и числовых значений:

import pandas as pd

from datetime import datetime

Создаём DataFrame с разными типами данных

data = {

"Дата": [datetime(2023, 1, 15), datetime(2023, 1, 16)],

"Продажи": [120, 45],

"Цена": [29990.50, 89990.99],

"Прибыль": [0.15, 0.20] # Проценты

}

df = pd.DataFrame(data)

Создаём объект ExcelWriter с движком xlsxwriter

with pd.ExcelWriter("отчёт_с_форматированием.xlsx", engine='xlsxwriter') as writer:

df.to_excel(writer, sheet_name="Продажи", index=False)

# Получаем доступ к объектам workbook и worksheet

workbook = writer.book

worksheet = writer.sheets["Продажи"]

# Настраиваем форматы

date_format = workbook.add_format({'num_format': 'dd.mm.yyyy'})

money_format = workbook.add_format({'num_format': '# ##0.00 ₽'})

percent_format = workbook.add_format({'num_format': '0%'})

# Применяем форматы к столбцам

worksheet.set_column('A:A', 12, date_format) # Столбец с датами

worksheet.set_column('C:C', 15, money_format) # Столбец с ценами

worksheet.set_column('D:D', 10, percent_format) # Столбец с процентами

Критическая деталь: XlsxWriter не может модифицировать существующие файлы Excel — только создавать новые. Если вам нужно дописать данные в существующий файл, используйте OpenPyXL (раздел 4).

Преимущества XlsxWriter перед стандартным to_excel():

  • 📈 Поддержка диаграмм и сводных таблиц;
  • 🖼️ Вставка изображений и комментариев;
  • 🔍 Оптимизация памяти при работе с большими файлами (через параметр constant_memory=True).

Установить библиотеку (pip install xlsxwriter)

Импортировать ExcelWriter из pandas

Создать DataFrame с нужными данными

Определить форматы для каждого типа данных (даты, валюта, проценты)

Применить форматы к соответствующим столбцам-->

3. Экспорт в Excel с OpenPyXL: работа с существующими файлами

В отличие от XlsxWriter, библиотека OpenPyXL умеет:

  • 🔄 Читать и модифицировать существующие файлы Excel;
  • 📂 Работать с несколькими листами одновременно;
  • 🎭 Поддерживать стили ячеек (цвета, шрифты, выравнивание).

Установка:

pip install openpyxl

Пример добавления DataFrame в существующий файл:

from openpyxl import load_workbook

import pandas as pd

Загружаем существующий файл

book = load_workbook("существующий_отчёт.xlsx")

writer = pd.ExcelWriter("существующий_отчёт.xlsx", engine='openpyxl')

writer.book = book

Записываем DataFrame на новый лист

df.to_excel(writer, sheet_name="Новые_данные", index=False)

writer.save()

⚠️ Внимание: При использовании OpenPyXL для больших DataFrame (>50К строк) может возникнуть ошибка MemoryError. В этом случае разбейте данные на части или используйте XlsxWriter для первоначальной записи, а OpenPyXL — только для доработки.

Кейс: вам нужно обновить только один лист в файле с 10 листами. С OpenPyXL это делается так:

# Загружаем файл, оставляя все листы нетронутыми

book = load_workbook("ежемесячный_отчёт.xlsx")

with pd.ExcelWriter("ежемесячный_отчёт.xlsx", engine='openpyxl') as writer:

writer.book = book

# Обновляем только лист "Январь"

if "Январь" in book.sheetnames:

writer.sheets["Январь"] = book["Январь"]

df.to_excel(writer, sheet_name="Январь", index=False)

4. Оптимизация экспорта для больших DataFrame (>100К строк)

При работе с большими объёмами данных стандартный to_excel() может:

  • 🐢 Замедляться до нескольких минут;
  • 💥 Выдавать ошибки нехватки памяти;
  • 📦 Создавать файлы размером в гигабайты.

Решения для оптимизации:

Проблема Решение Пример кода
Медленная запись Использовать engine='xlsxwriter' с constant_memory=True df.to_excel(writer, engine='xlsxwriter', constant_memory=True)
Большой размер файла Сохранять данные в .csv, а форматирование делать в Excel df.to_csv("данные.csv", index=False)
Ошибки памяти Разбивать DataFrame на чанки по 50К строк for chunk in np.array_split(df, 10): chunk.to_excel(writer)

Пример оптимизированного экспорта для 500К строк:

import numpy as np

Разбиваем DataFrame на чанки по 50К строк

chunks = np.array_split(df, len(df) // 50000 + 1)

with pd.ExcelWriter("большой_отчёт.xlsx", engine='xlsxwriter') as writer:

for i, chunk in enumerate(chunks):

chunk.to_excel(writer, sheet_name=f"Часть_{i+1}", index=False)

5. Сравнение Excel (.xlsx) и CSV: когда какой формат использовать

Выбор между .xlsx и .csv зависит от задачи. Вот сравнительная таблица по ключевым критериям:

Критерий Excel (.xlsx) CSV (.csv)
Поддержка нескольких листов ✅ Да ❌ Нет
Форматирование ячеек ✅ Да (цвета, шрифты, формулы) ❌ Нет
Размер файла 🟡 Средний (может раздуваться) ✅ Минимальный
Скорость записи/чтения 🟡 Медленнее для больших данных ✅ Быстрее в 3-5 раз
Совместимость ✅ Открывается в любом табличном редакторе ✅ Универсальный, но требует настройки разделителей

Когда выбирать .xlsx:

  • 📊 Нужно сохранить форматирование (цвета, формулы, диаграммы);
  • 📑 Требуется несколько листов в одном файле;
  • 👥 Файл будет открывать нетехнический пользователь (менеджер, бухгалтер).

Когда выбирать .csv:

  • 📈 Данные большого объёма (>100К строк);
  • 🔄 Нужна максимальная скорость записи/чтения;
  • 🤖 Файл будет обрабатываться автоматизированными системами.

Пример экспорта в CSV с настройкой разделителя (важно для российской локализации, где по умолчанию используется ;):

df.to_csv(

"данные.csv",

index=False,

sep=';', # Разделитель - точка с запятой

decimal=',', # Десятичный разделитель - запятая

encoding='utf-8-sig' # Кодировка с BOM для корректного отображения в Excel

)

Почему Excel неправильно открывает CSV с разделителем-запятой?

В российской версии Excel по умолчанию используется ; как разделитель, а , — как десятичный разделитель. Если ваш CSV создан с запятыми, Excel откроет его в одном столбце. Решения:

1. Использовать sep=';' при экспорте.

2. Импортировать CSV через "Мастер текстов" (Данные → Из текста/CSV).

3. Настроить региональные стандарты Windows на "Английский (США)".

6. Типичные ошибки и их решения

Даже опытные аналитики сталкиваются с проблемами при экспорте DataFrame в Excel. Вот топ-5 ошибок и способы их исправления:

  1. Ошибка: ValueError: Excel file format cannot be determined, you must specify an engine

    Причина: Не установлены библиотеки для работы с Excel (openpyxl или xlsxwriter).

    Решение: Установите недостающую библиотеку:

    pip install openpyxl xlsxwriter
  2. Ошибка: Вместо кириллицы отображаются ??????

    Причина: Неверная кодировка при сохранении.

    Решение: Укажите encoding='utf-8-sig' для CSV или используйте engine='xlsxwriter' для XLSX:

    df.to_excel("файл.xlsx", engine='xlsxwriter')
  3. Ошибка: MemoryError при экспорте большого DataFrame

    Причина: Недостаточно оперативной памяти для обработки данных.

    Решение: Разбейте DataFrame на части или используйте constant_memory=True:

    df.to_excel(writer, constant_memory=True)

Ещё две распространённые проблемы:

  • 🗓️ Дата сохраняется как число: Excel хранит даты как количество дней с 1900 года. Чтобы исправить, примените формат dd.mm.yyyy через XlsxWriter.
  • 💰 Числа округляются: Используйте параметр float_format="%.2f" для контроля точности:
    df.to_excel("файл.xlsx", float_format="%.2f")

7. Экспорт нескольких DataFrame в один файл Excel

Частая задача — сохранить несколько таблиц на разных листах одного файла. Например, у вас есть:

  • 📄 DataFrame с продажами;
  • 📄 DataFrame с остатками на складе;
  • 📄 DataFrame с аналитикой по регионам.

Решение с ExcelWriter:

with pd.ExcelWriter("полный_отчёт.xlsx", engine='xlsxwriter') as writer:

df_sales.to_excel(writer, sheet_name="Продажи", index=False)

df_stock.to_excel(writer, sheet_name="Склад", index=False)

df_regions.to_excel(writer, sheet_name="Регионы", index=False)

Если нужно добавить данные к существующему файлу (с другими листами), используйте OpenPyXL:

book = load_workbook("существующий_файл.xlsx")

with pd.ExcelWriter("существующий_файл.xlsx", engine='openpyxl') as writer:

writer.book = book

df_new.to_excel(writer, sheet_name="Новые_данные", index=False)

# Сохраняем все остальные листы

writer.sheets = {ws.title: ws for ws in book.worksheets}

Совет для больших файлов: если вам нужно объединить 10+ DataFrame, лучше создать отдельные файлы и потом объединить их через Python или Power Query в Excel. Это ускорит процесс и уменьшит риск ошибок памяти.

FAQ: Частые вопросы по экспорту DataFrame в Excel

Можно ли сохранить DataFrame в Excel без установки дополнительных библиотек?

Технически да — Pandas умеет сохранять в Excel без openpyxl/xlsxwriter, но только в формате .xls (Excel 97-2003), который имеет ограничение в 65К строк. Для современного .xlsx обязательно нужна одна из библиотек.

Как сохранить DataFrame в Excel с автофильтрами?

Используйте XlsxWriter и настройте автофильтр через worksheet.autofilter():

worksheet.autofilter('A1:D1000')  # Диапазон для фильтра

Полный пример в разделе 2.

Почему при открытии файла Excel выдаёт предупреждение о "разном формате ячеек"?

Это происходит, когда в одном столбце смешаны разные типы данных (например, числа и текст). Решения:

  1. Приведите все данные к одному типу перед экспортом (df['столбец'] = df['столбец'].astype(str));
  2. Используйте XlsxWriter и явно укажите формат для столбца;
  3. Сохраните в .csv и импортируйте в Excel через "Мастер текстов".

Как экспортировать DataFrame в Excel с закреплённой шапкой?

В методе to_excel() используйте параметр freeze_panes:

df.to_excel("файл.xlsx", freeze_panes=(1, 0))  # Закрепит первую строку

Для закрепления строки и столбца одновременно: freeze_panes=(1, 1).

Можно ли сохранить DataFrame в Excel с формулами?

Да, но не напрямую через to_excel(). Нужно:

  1. Создать файл с XlsxWriter;
  2. Записать данные как строки;
  3. Добавить формулы через worksheet.write_formula().

Пример:

worksheet.write_formula('E2', '=SUM(B2:D2)')  # Формула суммы