Создание Excel-файлов в Python: от простых таблиц до сложных отчётов

Введение: зачем создавать Excel из Python?

Работа с таблицами в формате Excel остаётся одной из самых востребованных задач в аналитике данных, финансовом моделировании и автоматизации отчётности. Python предлагает гибкие инструменты для генерации .xlsx-файлов — от простых таблиц с данными до сложных отчётов с формулами, диаграммами и условным форматированием. Но почему именно Python, а не ручной ввод в Microsoft Excel или Google Sheets?

Во-первых, автоматизация экономит часы работы: вместо копирования данных из базы или API вручную, скрипт сделает это за секунды. Во-вторых, масштабируемость — Python справится с таблицами на миллионы строк, где Excel начнёт «подвисать». В-третьих, воспроизводимость: один и тот же код будет генерировать одинаковые отчёты каждый месяц, исключая человеческие ошибки. Наконец, интеграция с другими инструментами (например, отправка файла по email или загрузка в облако) делает Python незаменимым для комплексных задач.

В этой статье мы разберём 5 практических способов создания Excel-файлов, от базовых до продвинутых, с примерами кода и сравнением производительности. Вы узнаете, как:

  • 📊 Создавать таблицы с данными из списков и словарей
  • 📈 Добавлять формулы, стили и диаграммы
  • ⚡ Оптимизировать работу с большими файлами (100K+ строк)
  • 🔄 Конвертировать данные из CSV/JSON в Excel
  • 🛠️ Обрабатывать типичные ошибки (кодировки, типы данных)
📊 Какой библиотекой вы обычно работаете с Excel в Python?
openpyxl
pandas
xlsxwriter
Другой
Никогда не пробовал

1. Базовый способ: библиотека openpyxl для простых таблиц

Openpyxl — самая популярная библиотека для работы с .xlsx в Python. Она позволяет создавать файлы «с нуля», редактировать существующие и поддерживает большинство функций Excel, включая формулы и стили. Установить её можно командой:

pip install openpyxl

Пример кода для создания файла с одной таблицей:

from openpyxl import Workbook

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

wb = Workbook()

ws = wb.active # Выбираем активный лист

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

ws['A1'] = "Товар"

ws['B1'] = "Цена"

ws['C1'] = "Количество"

data = [

["Ноутбук", 45000, 10],

["Смартфон", 32000, 25],

["Наушники", 8000, 50]

]

for row in data:

ws.append(row)

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

wb.save("товары.xlsx")

Этот код создаст файл с тремя колонками и четырьмя строками (включая заголовки). Обратите внимание на метод append() — он автоматически добавляет данные в следующую свободную строку, что удобно для динамического заполнения.

Указан корректный путь для сохранения|Имена листов не содержат запрещённых символов (/ \ * ?)|Данные не превышают лимиты Excel (1 048 576 строк)|Файл не открыт в другой программе-->

2. Работа с pandas: экспорт DataFrame в Excel

Если вы анализируете данные с помощью pandas, то экспорт в Excel сводится к одной строке кода. Эта библиотека идеальна для работы с табличными данными, особенно если они уже загружены из CSV, SQL или API. Установка:

pip install pandas openpyxl

Пример конвертации DataFrame в Excel:

import pandas as pd

Создаём DataFrame

data = {

"Дата": ["2023-01-01", "2023-01-02", "2023-01-03"],

"Продажи": [150, 200, 180],

"Регион": ["Москва", "СПб", "Екатеринбург"]

}

df = pd.DataFrame(data)

Экспортируем в Excel

df.to_excel("продажи.xlsx", index=False, sheet_name="Январь")

Ключевые параметры метода to_excel():

  • 📌 index=False — исключает колонку с индексами
  • 📌 sheet_name — имя листа (по умолчанию "Sheet1")
  • 📌 engine='openpyxl' — движок для работы с файлом (альтернатива: 'xlsxwriter')
  • 📌 startrow=2 — смещение начала данных (например, для заголовков)

Для работы с несколькими листами в одном файле используйте ExcelWriter:

with pd.ExcelWriter("отчёт.xlsx", engine='openpyxl') as writer:

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

df2.to_excel(writer, sheet_name="Возвраты", index=False)

3. Продвинутые возможности: xlsxwriter для сложных отчётов

Когда нужны формулы, условное форматирование или диаграммы, на помощь приходит xlsxwriter. Эта библиотека оптимизирована для записи и поддерживает почти все функции Excel, включая:

  • 📉 Встроенные и пользовательские диаграммы
  • 🎨 Стили ячеек (цвета, шрифты, границы)
  • 🧮 Формулы с относительными/абсолютными ссылками
  • 📊 Сводные таблицы (pivot tables)

Пример создания файла с формулой и стилями:

import xlsxwriter

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

workbook = xlsxwriter.Workbook('отчёт_с_формулами.xlsx')

worksheet = workbook.add_worksheet()

Добавляем данные

worksheet.write('A1', 'Стоимость')

worksheet.write('B1', 'Количество')

worksheet.write('C1', 'Итого')

worksheet.write('A2', 1000)

worksheet.write('B2', 5)

Добавляем формулу

worksheet.write('C2', '=A2*B2')

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

header_format = workbook.add_format({

'bold': True,

'font_color': 'white',

'bg_color': '#4472C4',

'border': 1

})

worksheet.set_row(0, None, header_format)

workbook.close()

Xlsxwriter не умеет читать существующие файлы (только создавать новые), но зато предлагает максимальную производительность при записи больших объёмов данных. Для файлов размером >100 МБ это часто лучший выбор.

Как добавить диаграмму в xlsxwriter

1. Создайте объект chart = workbook.add_chart({'type': 'column'})

2. Укажите диапазон данных: chart.add_series({'values': '=Sheet1!$C$2:$C$10'})

3. Вставьте диаграмму на лист: worksheet.insert_chart('E2', chart)

4. Настройте оформление через параметры title, x_axis_name и т.д.

4. Оптимизация для больших данных: потоковая запись

При работе с таблицами на 100 000+ строк стандартные методы (openpyxl или pandas) могут потреблять гигабайты памяти и работать минутами. Решения:

  1. Используйте xlsxwriter в режиме оптимизации:
    workbook = xlsxwriter.Workbook('большой_файл.xlsx', {'constant_memory': True})

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

  2. Записывайте данные порциями:
    for chunk in pd.read_csv('большой_файл.csv', chunksize=10000):
    

    chunk.to_excel(writer, sheet_name='Data', index=False, startrow=row_offset)

    row_offset += len(chunk)

  3. Отключите автоформатирование: В pandas добавьте float_format="%.2f", чтобы избежать преобразования чисел в экспоненциальный формат.

Критическая ошибка при работе с большими файлами: не используйте openpyxl для файлов >500 МБ — библиотека загружает весь файл в память, что приводит к сбоям.

Библиотека Макс. строк Поддержка формул Память (1M строк) Скорость записи
openpyxl 1M Да ~2 ГБ Медленно
pandas + openpyxl 1M Да ~1.5 ГБ Средне
xlsxwriter 10M+ Да ~500 МБ Быстро
pandas + xlsxwriter 10M+ Да ~800 МБ Очень быстро

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

Даже простой экспорт данных в Excel может столкнуться с проблемами. Вот TOP-5 ошибок и способы их исправления:

⚠️ Внимание: При использовании pandas с openpyxl для файлов >100 МБ может возникнуть ошибка MemoryError. Решение: переключитесь на engine='xlsxwriter' или разбейте данные на части.
  • 🔴 Ошибка кодировки: UnicodeEncodeError при сохранении русского текста.

    Решение: Явно укажите кодировку при открытии файла: open("файл.xlsx", encoding='utf-8') или используйте xlsxwriter, который корректно обрабатывает Unicode.

  • 🔴 Потеря точности чисел: В Excel числа типа 1.23456789 отображаются как 1.23457.

    Решение: В pandas используйте float_format="%.8f" или преобразуйте данные в строки с нужной точностью.

  • 🔴 Даты в неправильном формате: Excel преобразует 2023-01-01 в 44927 (внутренний формат дат).

    Решение: В pandas добавьте datetime_format='YYYY-MM-DD' или отформатируйте колонку заранее: df['Дата'] = df['Дата'].dt.strftime('%d.%m.%Y').

Ещё одна распространённая проблема — заблокированный файл. Если скрипт падает с ошибкой PermissionError: [Errno 13] Permission denied, проверьте:

  • 🔹 Файл не открыт в Excel или другой программе
  • 🔹 У пользователя есть права на запись в папку
  • 🔹 Путь к файлу не содержит запрещённых символов (/ \ * ?)

6. Автоматизация: отправка файла по email и загрузка в облако

Создание Excel-файла — только половина задачи. Часто требуется автоматически отправить его по email или загрузить в облачное хранилище. Вот как это сделать:

Отправка по email (с использованием smtplib):

import smtplib

from email.mime.multipart import MIMEMultipart

from email.mime.base import MIMEBase

from email import encoders

Создаём письмо

msg = MIMEMultipart()

msg['From'] = "отправитель@example.com"

msg['To'] = "получатель@example.com"

msg['Subject'] = "Автоматический отчёт"

Прикрепляем файл

with open("отчёт.xlsx", "rb") as file:

part = MIMEBase('application', 'octet-stream')

part.set_payload(file.read())

encoders.encode_base64(part)

part.add_header('Content-Disposition', 'attachment; filename="отчёт.xlsx"')

msg.attach(part)

Отправляем

with smtplib.SMTP('smtp.example.com', 587) as server:

server.starttls()

server.login("login", "password")

server.send_message(msg)

Загрузка в Google Drive (с использованием PyDrive):

from pydrive.auth import GoogleAuth

from pydrive.drive import GoogleDrive

Аутентификация

gauth = GoogleAuth()

gauth.LocalWebserverAuth() # Откроет браузер для авторизации

drive = GoogleDrive(gauth)

Загрузка файла

file_drive = drive.CreateFile({'title': 'отчёт.xlsx'})

file_drive.SetContentFile('отчёт.xlsx')

file_drive.Upload()

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

FAQ: ответы на частые вопросы

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

Технически да, но это крайне неудобно. Без библиотек придётся вручную формировать XML-структуру файла .xlsx (который на самом деле является ZIP-архивом с XML-файлами). Например, минимальный рабочий файл требует создания:

  • Файла xl/workbook.xml (структура книги)
  • Файла xl/worksheets/sheet1.xml (данные листа)
  • Файла [Content_Types].xml (типы содержимого)

На практике это занимает сотни строк кода. Гораздо проще установить openpyxl или xlsxwriter.

Как добавить диаграмму в Excel из Python?

С помощью xlsxwriter это делается в 4 шага:

# 1. Создаём данные

worksheet.write('A1', 'Категория')

worksheet.write('B1', 'Значение')

worksheet.write('A2', 'A')

worksheet.write('B2', 10)

worksheet.write('A3', 'B')

worksheet.write('B3', 20)

2. Добавляем диаграмму

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

3. Указываем диапазон данных

chart.add_series({'values': '=Sheet1!$B$2:$B$3', 'categories': '=Sheet1!$A$2:$A$3'})

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

worksheet.insert_chart('D2', chart)

Для других типов диаграмм измените параметр type на 'line', 'pie', 'bar' и т.д.

Почему Excel показывает числа в экспоненциальном формате (например, 1.23E+05 вместо 123000)?

Это происходит из-за автоматического форматирования Excel для «удобства чтения». Решения:

  • В pandas: используйте df.to_excel(..., float_format="%.0f") для целых чисел.
  • В openpyxl: примените стиль к ячейке: cell.number_format = '0'.
  • В Excel: после открытия файла выделите колонку → Формат ячеекЧисловой с 0 десятичных знаков.
Как защитить лист или книгу паролем?

Xlsxwriter поддерживает защиту на уровне листа:

worksheet.protect('пароль', {

'objects': True, # Защита объектов (фигур, диаграмм)

'scenarios': True, # Защита сценариев

'format_cells': False, # Разрешить форматирование ячеек

'insert_columns': False

})

Для защиты всей книги в openpyxl:

from openpyxl import Workbook

wb = Workbook()

wb.security = WorkbookProtection(workbookPassword='пароль', lockStructure=True)

wb.save('защищённый.xlsx')

Обратите внимание: парольная защита в Excel легко взламывается специализированными инструментами. Для конфиденциальных данных используйте шифрование файла (например, pyAesCrypt).

Какая библиотека самая быстрая для записи 1 миллиона строк?

Тесты на стандартном ноутбуке (Intel i5, 16 ГБ RAM) показывают следующие результаты:

Библиотека Время записи Потребление памяти
openpyxl ~120 секунд ~3.2 ГБ
pandas + openpyxl ~90 секунд ~2.8 ГБ
xlsxwriter (обычный режим) ~45 секунд ~1.5 ГБ
xlsxwriter (constant_memory=True) ~30 секунд ~800 МБ

Для максимальной производительности используйте xlsxwriter с оптимизацией памяти. Если нужны формулы или диаграммы — примиритесь с немного меньшей скоростью.