Экспорт данных из Python в Excel: полное руководство с примерами кода

Введение: зачем Python нужна связка с Excel

Excel остаётся стандартом де-факто для хранения и анализа табличных данных в бизнес-среде, несмотря на рост популярности специализированных инструментов. А Python, в свою очередь, стал лидирующим языком для обработки данных, автоматизации и машинного обучения. Их комбинация позволяет решать задачи, которые по отдельности были бы либо невозможны, либо крайне трудоёмки.

Представьте: вы обработали миллион строк данных с помощью pandas, применили сложные фильтры, рассчитали статистику — и теперь нужно предоставить результат коллегам, которые работают только в Microsoft Excel. Или наоборот: вам прислали отчёт в формате .xlsx, который нужно загрузить в Python для дальнейшего анализа. В обоих случаях умение экспортировать данные из Python в Excel становится критически важным навыком.

В этой статье мы разберём 5 основных способов сохранения данных в Excel из Python — от простейших методов для начинающих до продвинутых техник с форматированием, формулами и даже сводными таблицами. Вы узнаете, когда использовать pandas, а когда лучше обратиться к openpyxl или xlsxwriter, как избежать типичных ошибок при работе с кодировками и большими файлами, а также получите готовые шаблоны кода для самых распространённых задач.

1. Самый простой способ: pandas.to_excel()

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

Основные преимущества метода:

  • 🔹 Простота: одна команда для экспорта данных
  • 🔹 Поддержка нескольких листов: можно сохранять несколько DataFrame в один файл на разных листах
  • 🔹 Автоматическое определение типов данных: pandas пытается сохранить формат чисел, дат и текста
  • 🔹 Интеграция с другими инструментами pandas: легко экспортировать отфильтрованные или агрегированные данные

Базовый синтаксис выглядит так:

import pandas as pd

Создаём DataFrame

data = {'Имя': ['Анастасия', 'Дмитрий', 'Екатерина'],

'Возраст': [28, 34, 23],

'Город': ['Москва', 'Санкт-Петербург', 'Казань']}

df = pd.DataFrame(data)

Сохраняем в Excel

df.to_excel('данные_о_пользователях.xlsx', index=False, sheet_name='Лист1')

Обратите внимание на параметры:

  • index=False — отключает сохранение номера строки как отдельного столбца
  • sheet_name — позволяет задать имя листа (по умолчанию 'Sheet1')
  • engine — можно явно указать движок ('openpyxl' или 'xlsxwriter')
with pd.ExcelWriter('отчёт.xlsx', engine='openpyxl') as writer:

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

df2.to_excel(writer, sheet_name='Клиенты', index=False)

-->

2. Работа с большими файлами: оптимизация памяти и скорости

Когда речь идёт о файлах размером более 100 МБ или таблицах с сотнями тысяч строк, стандартный подход с pandas может оказаться неэффективным. Основные проблемы: высокое потребление памяти, медленная запись и даже крах программы. В таких случаях нужно использовать специализированные техники.

Вот ключевые стратегии для работы с большими данными:

  • 📊 Пакетная запись: разбивайте данные на части и сохраняйте поочерёдно
  • Отключение автофильтра: это ускоряет запись на 15-30%
  • 🗃️ Использование оптимизированных форматов: .xlsx vs .xlsb
  • 🔄 Потоковая запись: для действительно огромных файлов (>1 ГБ)

Пример оптимизированного сохранения большого DataFrame:

# Отключаем автофильтр и используем xlsxwriter для скорости

with pd.ExcelWriter('большой_отчёт.xlsx',

engine='xlsxwriter',

options={'strings_to_urls': False}) as writer:

df.to_excel(writer,

sheet_name='Данные',

index=False,

freeze_panes=(1, 0)) # Фиксируем шапку

Для файлов размером более 1 ГБ рассмотрите вариант с SQLite как промежуточным хранилищем или использование библиотеки dask для обработки данных частями. Также стоит помнить, что формат .xlsb (Excel Binary) часто работает быстрее, чем .xlsx, но не поддерживает все функции последнего.

📊 Какой объём данных вы обычно экспортируете в Excel?
До 10 000 строк
10 000–100 000 строк
100 000–1 000 000 строк
Более 1 000 000 строк

3. Продвинутое форматирование с openpyxl

Если вам нужно не просто сохранить данные, а создать полноценный отчёт с цветными ячейками, объединёнными строками, формулами и даже графиками — библиотека openpyxl станет вашим лучшим помощником. В отличие от pandas, она позволяет управлять каждым аспектом оформления Excel-файла на уровне отдельных ячеек.

Основные возможности openpyxl:

  • 🎨 Стилизация ячеек: шрифты, цвета, границы, выравнивание
  • 📏 Объединение ячеек: создание сложных заголовков
  • 📊 Вставка формул: автоматические расчёты прямо в файле
  • 📈 Построение графиков: диаграммы и сводные таблицы
  • 🔗 Гиперссылки: связь между листами или внешними ресурсами

Пример создания форматированного отчёта:

from openpyxl import Workbook

from openpyxl.styles import Font, Alignment, Border, Side, PatternFill

from openpyxl.utils import get_column_letter

Создаём новую книгу

wb = Workbook()

ws = wb.active

ws.title = "Отчёт по продажам"

Данные

data = [

["Регион", "Квартал", "Продажи", "Прибыль"],

["Центр", "Q1", 1500000, 300000],

["Центр", "Q2", 1800000, 360000],

["Юг", "Q1", 1200000, 240000]

]

Записываем данные

for row in data:

ws.append(row)

Форматируем заголовок

header_font = Font(bold=True, size=12, color="FFFFFF")

header_fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type="solid")

header_alignment = Alignment(horizontal="center")

for cell in ws[1]:

cell.font = header_font

cell.fill = header_fill

cell.alignment = header_alignment

Добавляем границы ко всем ячейкам с данными

thin_border = Border(left=Side(style='thin'),

right=Side(style='thin'),

top=Side(style='thin'),

bottom=Side(style='thin'))

for row in ws.iter_rows(min_row=2, max_row=len(data), min_col=1, max_col=4):

for cell in row:

cell.border = thin_border

Добавляем формулу для подсчёта общей прибыли

ws[f'D{len(data)+1}'] = f"=SUM(D2:D{len(data)})"

ws[f'D{len(data)+1}'].font = Font(bold=True)

Сохраняем файл

wb.save("отчёт_по_продажам.xlsx")

Как добавить сводную таблицу через openpyxl?

Для создания сводной таблицы через openpyxl нужно сначала определить источник данных, затем создать объект PivotTable. Вот базовый пример:

from openpyxl.worksheet.pivot_table import PivotTable, Reference

Предполагаем, что данные находятся на листе "Данные" в диапазоне A1:D100

data_ref = Reference(ws, min_col=1, min_row=1, max_col=4, max_row=100)

Создаём сводную таблицу на новом листе

pt_sheet = wb.create_sheet("Сводная")

pt = PivotTable(data_ref, "PivotTable1")

pt.add_row_fields(0) # Первый столбец как строки

pt.add_column_fields(2) # Третий столбец как столбцы

pt.add_data_field(3) # Четвёртый столбец как данные

pt_sheet.add_table(pt)

wb.save("отчёт_со_сводной.xlsx")

Обратите внимание, что для работы со сводными таблицами потребуется openpyxl версии 3.0 или новее.

4. Создание графиков и диаграмм с xlsxwriter

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

Процесс создания диаграммы состоит из трёх этапов:

  1. Подготовка данных в рабочей книге
  2. Создание объекта диаграммы с указанием типа
  3. Настройка параметров и добавление на лист

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

import xlsxwriter

Создаём книгу и лист

workbook = xlsxwriter.Workbook('диаграмма_продаж.xlsx')

worksheet = workbook.add_worksheet('Статистика')

Данные для диаграммы

categories = ['Q1', 'Q2', 'Q3', 'Q4']

values = [1200000, 1800000, 1500000, 2100000]

Записываем данные

worksheet.write('A1', 'Квартал')

worksheet.write('B1', 'Продажи')

for row, (category, value) in enumerate(zip(categories, values), start=2):

worksheet.write(f'A{row}', category)

worksheet.write(f'B{row}', value)

Создаём диаграмму

chart = workbook.add_chart({'type': 'column'})

Настраиваем данные для диаграммы

chart.add_series({

'name': '=Статистика!$B$1',

'categories': '=Статистика!$A$2:$A$5',

'values': '=Статистика!$B$2:$B$5',

'fill': {'color': '#4F81BD'},

'border': {'color': '#FFFFFF', 'width': 1},

})

Настраиваем оси

chart.set_x_axis({'name': 'Кварталы', 'name_font': {'size': 12, 'bold': True}})

chart.set_y_axis({'name': 'Сумма продаж (руб)', 'name_font': {'size': 12, 'bold': True}})

chart.set_title({'name': 'Динамика продаж по кварталам 2023 года'})

Вставляем диаграмму на лист

worksheet.insert_chart('D2', chart)

workbook.close()

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

Убедитесь что данные расположены последовательно без пустых строк|Проверьте формат чисел (Excel может неправильно интерпретировать большие числа)|Задайте понятные заголовки столбцов|Отсортируйте данные если требуется хронологический порядок|Проверьте что нет скрытых символов в тексте (особенно при экспорте из веб)-->

5. Работа с формулами и ссылками

Одной из самых мощных возможностей Excel являются формулы, и при экспорте данных из Python их можно (и часто нужно) сохранять. Это позволяет создавать динамические отчёты, где итоговые значения пересчитываются автоматически при изменении исходных данных.

Все три рассмотренные библиотеки (pandas, openpyxl, xlsxwriter) поддерживают работу с формулами, но делают это по-разному:

Библиотека Способ добавления формул Особенности Пример
pandas Через параметр formula в ExcelWriter Ограниченная поддержка, формулы добавляются после экспорта данных writer.book['Лист1'].cell(row=5, column=3).value = '=SUM(C2:C4)'
openpyxl Прямая запись в ячейку как строки, начинающейся с = Полная поддержка всех функций Excel, можно использовать именованные диапазоны ws['D10'] = '=SUM(D2:D9)'
xlsxwriter Через метод write_formula() Поддержка массивов формул, оптимизирован для производительности worksheet.write_formula('D10', '{=SUM(D2:D9*E2:E9)}')

Важный нюанс: при работе с формулами всегда указывайте абсолютные ссылки (с символом $), если хотите зафиксировать диапазон. В противном случае при копировании ячеек Excel будет автоматически сдвигать ссылки, что может привести к ошибкам.

Пример сложной формулы с условной логикой:

# Добавляем формулу с несколькими условиями через openpyxl

ws['E2'] = '=IF(D2>1000000, "Высокий", IF(D2>500000, "Средний", "Низкий"))'

Или через xlsxwriter с использованием именованных диапазонов

workbook.define_name('TotalSales', '=Лист1!$D$2:$D$100')

worksheet.write_formula('D101', '=SUM(TotalSales)')

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

Даже опытные разработчики сталкиваются с проблемами при экспорте данных в Excel. Вот наиболее распространённые ошибки и способы их избежать:

⚠️ Внимание: Если вы получаете ошибку ValueError: Excel file format cannot be determined, you must specify an engine, это означает что pandas не может определить формат файла. Явно укажите движок: df.to_excel('file.xlsx', engine='openpyxl').

Частые проблемы и решения:

  • 🔴 Проблемы с кодировкой: Используйте encoding='utf-8-sig' для файлов CSV, которые потом конвертируете в Excel, или явно указывайте кодировку при чтении данных
  • 🔴 Потеря форматирования дат: Преобразуйте столбцы с датами в формат datetime перед экспортом: df['date_column'] = pd.to_datetime(df['date_column'])
  • 🔴 Ограничение на 65536 строк в .xls: Всегда сохраняйте в формате .xlsx (или используйте .xlsb для очень больших файлов)
  • 🔴 Зависание при работе с большими файлами: Используйте chunksize в pandas или потоковую запись через openpyxl
  • 🔴 Формулы не работают после экспорта: Убедитесь что ячейки имеют правильный формат (не текстовый) и используйте английские названия функций

Особого внимания требует работа с датами и временем. Excel хранит даты как количество дней с 1 января 1900 года (или 1904 в Mac-версии), поэтому при экспорте из Python могут возникать расхождения. Всегда проверяйте результат:

# Правильный способ экспорта дат

df['date_column'] = pd.to_datetime(df['date_column'])

df.to_excel('dates.xlsx', engine='openpyxl', date_format='dd.mm.yyyy')

⚠️ Внимание: При использовании xlsxwriter для создания файлов с формулами, которые потом будут открываться в openpyxl, некоторые сложные формулы могут не сохраняться корректно. В таких случаях используйте openpyxl и для создания, и для чтения файла.

7. Автоматизация: создание шаблонов и массовый экспорт

Когда нужно регулярно генерировать отчёты по одному и тому же шаблону, имеет смысл создать базовый файл-шаблон и затем только обновлять в нём данные. Это экономит время и гарантирует единообразие оформления.

Алгоритм работы с шаблонами:

  1. Создайте вручную файл Excel с нужным оформлением (логотипы, заголовки, формулы)
  2. Определите "якорные ячейки" — места, куда будут вставляться данные из Python
  3. Напишите скрипт, который открывает шаблон, обновляет данные и сохраняет новый файл
  4. Автоматизируйте процесс через cron (Linux) или Task Scheduler (Windows)

Пример работы с шаблоном:

from openpyxl import load_workbook

Загружаем шаблон

template_path = 'шаблон_отчёта.xlsx'

output_path = 'отчёт_2023_10.xlsx'

wb = load_workbook(template_path)

ws = wb.active

Обновляем данные (предполагаем что данные начинаются с ячейки B3)

new_data = [

["Отдел продаж", 1200000, 240000],

["Отдел маркетинга", 800000, 160000],

["IT-отдел", 1500000, 300000]

]

for row_idx, row_data in enumerate(new_data, start=3):

for col_idx, value in enumerate(row_data, start=2):

ws.cell(row=row_idx, column=col_idx, value=value)

Пересчитываем все формулы в книге

wb.guess_types = True

for sheet in wb:

for row in sheet:

for cell in row:

if cell.data_type == 'f': # Если это формула

cell.value = cell.value # Принудительный пересчёт

Сохраняем новый файл

wb.save(output_path)

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

import os

from openpyxl import Workbook

Список клиентов

clients = [

{"id": 1001, "name": "ООО Ромашка", "data": [...]},

{"id": 1002, "name": "ИП Васильев", "data": [...]},

# ... другие клиенты

]

Папка для сохранения отчётов

os.makedirs('отчёты_клиентов', exist_ok=True)

for client in clients:

wb = Workbook()

ws = wb.active

ws.title = f"Клиент {client['id']}"

# Заполняем данными клиента

ws.append([client['name'], "Отчёт за октябрь 2023"])

for row in client['data']:

ws.append(row)

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

filename = f"отчёты_клиентов/отчёт_{client['id']}_{client['name']}.xlsx"

wb.save(filename)

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

Можно ли сохранить DataFrame в Excel без pandas?

Да, можно использовать библиотеки openpyxl или xlsxwriter напрямую. Вот пример с openpyxl:

from openpyxl import Workbook

wb = Workbook()

ws = wb.active

Предполагаем что data - это список списков

data = [[1, 2, 3], [4, 5, 6]]

for row in data:

ws.append(row)

wb.save("data.xlsx")

Однако для сложных DataFrame с разными типами данных pandas предоставляет более удобные инструменты.

Как сохранить DataFrame в существующий Excel-файл, не стирая другие листы?

Используйте ExcelWriter с параметром mode='a' (append) и явно укажите движок openpyxl:

with pd.ExcelWriter('существующий_файл.xlsx',

engine='openpyxl',

mode='a',

if_sheet_exists='replace') as writer:

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

Параметр if_sheet_exists может принимать значения:

  • 'replace' — заменить существующий лист
  • 'overlay' — добавить данные поверх существующих
  • 'error' — выдать ошибку если лист существует

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

Это типичная проблема при:

  • Использовании устаревшей версии библиотеки (обновите openpyxl или xlsxwriter)
  • Неправильном закрытии файла (всегда используйте контекстный менеджер with)
  • Попытке сохранить недопустимые символы в именах листов
  • Конфликте форматов (например, сохранение в .xls вместо .xlsx)

Решение: обновите библиотеки и проверьте код на наличие явного закрытия файла. Также можно попробовать открыть файл через LibreOffice Calc — он менее привередлив к формату.

Как экспортировать данные с сохранением стилей из исходного файла?

Для этого нужно:

  1. Открыть исходный файл с помощью openpyxl в режиме load_workbook
  2. Скопировать стили с нужных ячеек
  3. Применить эти стили к новым данным
  4. Сохранить файл с тем же именем или новым

Пример копирования стиля:

from openpyxl import load_workbook

from copy import copy

wb = load_workbook('шаблон.xlsx')

ws = wb.active

Копируем стиль с ячейки A1

source_cell = ws['A1']

new_cell = ws['B10']

new_cell.value = "Новые данные"

new_cell.font = copy(source_cell.font)

new_cell.fill = copy(source_cell.fill)

new_cell.border = copy(source_cell.border)

wb.save('обновлённый_файл.xlsx')

Какая библиотека самая быстрая для экспорта больших данных?

По тестам на данных объёмом 1 млн строк:

  1. xlsxwriter — самая быстрая (оптимизирована для записи)
  2. openpyxl — средняя скорость, но больше возможностей для чтения/изменения
  3. pandas.to_excel() — самая медленная, но самая простая в использовании

Для максимальной производительности используйте xlsxwriter с отключёнными дополнительными функциями:

writer = pd.ExcelWriter('big_data.xlsx',

engine='xlsxwriter',

options={'strings_to_urls': False,

'strings_to_formulas': False,

'default_date_format': 'yyyy-mm-dd'})