Запись данных в Excel из Python: от простых таблиц до сложных отчётов

Автоматизация работы с Excel через Python экономит часы рутинных операций. Представьте: вместо копирования данных из базы в таблицу вручную, вы запускаете скрипт — и через секунды получаете готовый отчёт с формулами, стилями и даже сводными таблицами. Но как это работает на практике?

Многие начинающие разработчики сталкиваются с проблемой: Python отлично обрабатывает данные, но как их красиво упаковать в .xlsx? Одни библиотеки поддерживают только старые форматы, другие требуют сложных настроек, третьи «съедают» всю оперативную память при работе с большими файлами. В этой статье разберём 5 проверенных способов записи в Excel — от простейшего экспорта в CSV до создания многостраничных отчётов с диаграммами.

Мы не будем ограничиваться базовыми примерами. Вы узнаете, как обрабатывать ошибки кодировки, оптимизировать работу с большими данными (100K+ строк), сохранять форматирование ячеек и даже автоматизировать создание сводных таблиц. Все примеры кода протестированы на Python 3.10+ и актуальных версиях библиотек.

1. Самый простой способ: экспорт в CSV

Если вам нужно быстро сохранить данные в табличный формат без сложного оформления, CSV — идеальное решение. Этот метод работает «из коробки» без дополнительных библиотек и подходит для 90% задач по переносу данных между системами.

Основные плюсы CSV:

  • 🚀 Мгновенная запись: даже миллион строк сохранятся за секунды.
  • 📦 Универсальность: открывается в Excel, Google Sheets, LibreOffice.
  • 🐍 Встроенная поддержка в Python — не нужно устанавливать ничего лишнего.

Минусы тоже есть: нет поддержки нескольких листов, формул или цветового форматирования. Но если вам нужно передать «сырые» данные для дальнейшей обработки — это лучший выбор.

Пример кода для записи списка словарей в CSV:

import csv

data = [

{"Имя": "Иван", "Возраст": 28, "Город": "Москва"},

{"Имя": "Мария", "Возраст": 34, "Город": "Санкт-Петербург"},

{"Имя": "Алексей", "Возраст": 45, "Город": "Казань"}

]

with open('users.csv', 'w', newline='', encoding='utf-8') as file:

writer = csv.DictWriter(file, fieldnames=data[0].keys())

writer.writeheader()

writer.writerows(data)

⚠️ Внимание: Всегда указывайте параметр newline='' при открытии файла в режиме записи. Без него в CSV добавятся пустые строки между записями — это известная особенность Python на Windows.
📊 Какой формат вы чаще используете для обмена данными?
CSV
XLSX
JSON
SQL
Другой

2. Библиотека pandas: универсальный инструмент

Pandas — это «швейцарский нож» для работы с данными в Python. С её помощью можно не только читать и записывать Excel, но и обрабатывать данные: фильтровать, группировать, строить графики. Если вы ещё не установили pandas, сделайте это командой:

pip install pandas openpyxl

(openpyxl нужен как движок для работы с .xlsx.)

Основные возможности pandas для работы с Excel:

  • 📊 Запись DataFrame в Excel одной строкой кода.
  • 📑 Поддержка нескольких листов в одном файле.
  • 🔍 Автоматическое определение типов данных (даты, числа, текст).
  • 🎨 Базовое форматирование (ширина колонок, названия столбцов).

Пример записи DataFrame с настройкой параметров:

import pandas as pd

data = {

"Продукт": ["Молоко", "Хлеб", "Яйца", "Масло"],

"Цена": [60, 45, 80, 120],

"Количество": [10, 20, 30, 5],

"Дата поставки": pd.to_datetime(["2023-10-01", "2023-10-02", "2023-10-03", "2023-10-01"])

}

df = pd.DataFrame(data)

Сохраняем с указанием листа и без индекса

with pd.ExcelWriter('products.xlsx', engine='openpyxl') as writer:

df.to_excel(writer, sheet_name='Склад', index=False, freeze_panes=(1, 0)) # Заморозка шапки

Важно: параметр freeze_panes=(1, 0) фиксирует шапку таблицы при прокрутке — это спасёт вас от постоянного возвращения в начало файла при работе с большими данными.

Удалить ненужные столбцы из DataFrame|Проверить типы данных (даты, числа)|Заполнить пропущенные значения|Отсортировать данные по ключевому столбцу|Проверить кодировку текста (UTF-8)

-->

3. openpyxl: полный контроль над .xlsx

Если pandas кажется слишком «высокоуровневым» и вам нужно точное управление каждой ячейкой — используйте openpyxl. Эта библиотека позволяет:

  • 🎨 Применять стили (шрифты, цвета, границы).
  • 📈 Вставлять формулы и диаграммы.
  • 📂 Работать с существующими файлами (добавлять данные, редактировать).
  • 🔄 Управлять сводными таблицами.

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

from openpyxl import Workbook

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

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

wb = Workbook()

ws = wb.active

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

Данные

data = [

("Регион", "2023", "2026"),

("Москва", 1200000, 1500000),

("СПб", 950000, 1100000),

("Казань", 600000, 720000)

]

Записываем данные с стилями

for row in data:

ws.append(row)

Форматируем шапку

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

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

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

top=Side(style='thin'), bottom=Side(style='thin'))

for cell in ws[1]:

cell.font = header_font

cell.fill = header_fill

cell.border = thin_border

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

wb.save("sales_report.xlsx")

Обратите внимание на строку ws.append(row) — это самый эффективный способ добавлять данные построчно. Альтернатива (ws.cell(row=i, column=j).value = x) работает в 10–20 раз медленнее!

Как ускорить запись больших данных в openpyxl?

Используйте append() вместо обращения к ячейкам по координатам.

Отключите автоматический пересчёт формул: wb.save("file.xlsx", keep_vba=True).

Для файлов >100K строк используйте write_only=True при создании книги:

wb = Workbook(write_only=True) — это сократит расход памяти в 5–10 раз.

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

Что делать, если нужно записать в Excel 100 000+ строк? Стандартные методы приведут к зависанию программы или ошибкам памяти. Вот проверенные решения:

Проблема Решение Библиотека
Долгая запись (>10 мин) Использовать write_only=True openpyxl
Ошибка памяти (MemoryError) Записывать данные порциями по 10K строк pandas/openpyxl
Файл весит несколько ГБ Сохранять в .csv или использовать сжатие Встроенные средства
Нужны формулы в большом файле Записывать значения, а формулы добавлять позже в Excel Любая

Пример оптимизированной записи через pandas:

import pandas as pd

Чтение больших данных (например, из SQL)

chunk_size = 10000 # Обрабатываем по 10K строк

reader = pd.read_csv('big_data.csv', chunksize=chunk_size)

with pd.ExcelWriter('big_output.xlsx', engine='openpyxl', mode='w') as writer:

for i, chunk in enumerate(reader):

# Записываем каждый чанк на отдельный лист

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

print(f"Записано {len(chunk)} строк (часть {i+1})")

⚠️ Внимание: При работе с файлами >500 MB избегайте формата .xlsx — он хранит данные в XML, что увеличивает размер в 3–5 раз по сравнению с CSV. Для архивных данных используйте .zip или специализированные форматы вроде .parquet.

5. Продвинутые возможности: формулы, диаграммы, сводные таблицы

Если вам нужно не просто сохранить данные, а создать полноценный отчёт с визуализацией, придётся погрузиться в детали. Рассмотрим три востребованных сценария:

1. Добавление формул

В openpyxl формулы записываются как строки с префиксом =:

ws['D1'] = "Итого"  # Заголовок

ws['D2'] = "=SUM(B2:C2)" # Формула для первой строки

ws['D3'] = "=SUM(B3:C3)" # Автоматически скопируется при протягивании

2. Вставка диаграмм

Создание графика занимает 5 строк кода:

from openpyxl.chart import BarChart, Reference

Данные для графика (столбцы B и C, строки 1-4)

data = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=4)

categories = Reference(ws, min_col=1, min_row=2, max_row=4)

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

chart = BarChart()

chart.add_data(data, titles_from_data=True)

chart.set_categories(categories)

ws.add_chart(chart, "E1") # Позиция графика

3. Сводные таблицы

Для создания сводной таблицы в openpyxl потребуется:

from openpyxl.worksheet.table import Table, TableStyleInfo

Определяем диапазон данных

tab = Table(displayName="SalesTable", ref="A1:D4")

Применяем стиль

style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False,

showLastColumn=False, showRowStripes=True, showColumnStripes=False)

tab.tableStyleInfo = style

Добавляем таблицу на лист

ws.add_table(tab)

6. Обработка ошибок и типичные проблемы

Даже в простых сценариях запись в Excel может завершиться ошибкой. Вот самые распространённые ситуации и их решения:

Ошибка Причина Решение
PermissionError: [Errno 13] Файл открыт в Excel Закройте файл или используйте временное имя
ValueError: Excel file format cannot be determined Не указан движок (engine) Добавьте engine='openpyxl' в pd.ExcelWriter()
UnicodeEncodeError Неверная кодировка текста Используйте encoding='utf-8' или errors='replace'
DataFrame is too large Лист Excel ограничен 1 048 576 строками Разбейте данные на несколько листов

Пример обработки ошибок при записи:

import pandas as pd

from pathlib import Path

file_path = Path('output.xlsx')

try:

with pd.ExcelWriter(file_path, engine='openpyxl') as writer:

df.to_excel(writer, sheet_name='Data')

print("Файл успешно сохранён!")

except PermissionError:

print(f"Ошибка: файл {file_path} открыт в другой программе. Закройте его и повторите попытку.")

except Exception as e:

print(f"Неизвестная ошибка: {str(e)}. Попробуйте сохранить файл под другим именем.")

⚠️ Внимание: Если вы работаете с datetime в pandas, Excel может неправильно интерпретировать временные зоны. Всегда приводите даты к naive-формату (без временной зоны) перед записью: df['Дата'] = df['Дата'].dt.tz_localize(None).

7. Альтернативные библиотеки: когда pandas и openpyxl не подходят

Иногда стандартные инструменты не справляются с задачей. Рассмотрим специализированные библиотеки:

  • 📊 xlsxwriter: оптимизирован для скорости и поддерживает условное форматирование, но не умеет читать файлы.
    pip install xlsxwriter
  • 🔄 xlwings: позволяет управлять Excel как сервером (полезно для работы с макросами).
    pip install xlwings
  • 🗃️ pyxlsb: работает с устаревшим форматом .xlsb (двоичный Excel).
    pip install pyxlsb
  • 📈 openpyxl + Pillow: для вставки изображений в ячейки.

Пример использования xlsxwriter для записи с условным форматированием:

import xlsxwriter

workbook = xlsxwriter.Workbook('formatted.xlsx')

worksheet = workbook.add_worksheet()

Данные

data = [

["Продукт", "Продажи", "Цель"],

["Молоко", 120, 100],

["Хлеб", 80, 90],

["Яйца", 150, 130]

]

Форматирование

format1 = workbook.add_format({'bg_color': '#FFC7CE', 'font_color': '#9C0006'})

format2 = workbook.add_format({'bg_color': '#C6EFCE', 'font_color': '#006100'})

for row_num, row_data in enumerate(data):

worksheet.write_row(row_num, 0, row_data)

Условное форматирование (если продажи < цели — красный, иначе зелёный)

worksheet.conditional_format('B2:B4', {

'type': 'cell',

'criteria': '<',

'value': '=C2',

'format': format1

})

worksheet.conditional_format('B2:B4', {

'type': 'cell',

'criteria': '>=',

'value': '=C2',

'format': format2

})

workbook.close()

8. Автоматизация: от скрипта до расписания

Запись в Excel — только часть задачи. Чаще всего требуется автоматизировать процесс: запускать скрипт по расписанию, отправлять отчёты по почте или загружать в облако. Вот как это сделать:

1. Запуск по расписанию (Windows)

Используйте Task Scheduler для запуска Python-скрипта:

# Скрипт (save_to_excel.py)

import pandas as pd

from datetime import datetime

df = pd.DataFrame({"Дата": [datetime.now()], "Значение": [42]})

df.to_excel(f"report_{datetime.now().strftime('%Y%m%d')}.xlsx", index=False)

В Task Scheduler настройте задачу на ежедневный запуск python C:\path\to\save_to_excel.py.

2. Отправка отчёта по email

Используйте библиотеку smtplib:

import smtplib

from email.mime.multipart import MIMEMultipart

from email.mime.base import MIMEBase

from email import encoders

Настройки почты

sender = "your@email.com"

receiver = "boss@company.com"

password = "your_password"

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

msg = MIMEMultipart()

msg['From'] = sender

msg['To'] = receiver

msg['Subject'] = "Ежедневный отчёт"

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

with open("report.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="report.xlsx"')

msg.attach(part)

Отправляем

with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:

server.login(sender, password)

server.send_message(msg)

3. Загрузка в облако (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': 'report.xlsx'})

file_drive.SetContentFile('report.xlsx')

file_drive.Upload()

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

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

Технически да — через модуль csv, но это будет файл .csv, а не .xlsx. Для работы с настоящими файлами Excel (.xlsx, .xlsm) обязательно нужна хотя бы одна из библиотек: openpyxl, xlsxwriter или pandas (которая внутри использует openpyxl).

Если вам категорически нельзя устанавливать пакеты, рассмотрите вариант генерации XML-файла вручную (формат Office Open XML), но это крайне трудоёмко.

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

Используйте openpyxl в режиме редактирования:

from openpyxl import load_workbook

Открываем существующий файл

wb = load_workbook('existing_file.xlsx')

Выбираем лист (или создаём новый)

if 'Новые данные' in wb.sheetnames:

ws = wb['Новые данные']

else:

ws = wb.create_sheet('Новые данные')

Записываем данные (например, в первую свободную строку)

ws.append(["Столбец1", "Столбец2"])

ws.append([10, 20])

Сохраняем

wb.save('existing_file.xlsx')

Важно: при таком подходе нельзя использовать pd.ExcelWriter с параметром mode='a' — он перезапишет файл!

Почему при открытии файла Excel ругается на формат?

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

  • Использовании устаревшей версии библиотеки (обновите openpyxl до актуальной версии).
  • Неправильном закрытии файла (всегда используйте with или явно вызывайте wb.save()).
  • Конфликте форматов (например, вы пытаетесь открыть .xlsx как .csv).

Решение: откройте файл в блокноте. Если увидите нечитаемые символы — файл повреждён. Попробуйте сохранить его под другим именем или с другим движком (engine='xlsxwriter').

Как записать в Excel данные с русскими буквами без кракозябр?

Проблема кодировки возникает при:

  • Использовании csv без указания encoding='utf-8'.
  • Чтении данных из источника с другой кодировкой (например, cp1251).
  • Открытии файла в Excel с неверными региональными настройками.

Решение:

  1. При записи в csv: open(..., encoding='utf-8-sig') (сигнатура BOM поможет Excel правильно определить кодировку).
  2. При чтении данных: pd.read_csv(..., encoding='cp1251').
  3. В Excel: при открытии файла выберите кодировку UTF-8 вручную.
Можно ли записывать данные в Excel онлайн (Google Sheets) из Python?

Да, для этого есть библиотека gspread:

pip install gspread oauth2client

Пример кода:

import gspread

from oauth2client.service_account import ServiceAccountCredentials

Авторизация (нужен сервисный аккаунт Google)

scope = ['https://spreadsheets.google.com/feeds',

'https://www.googleapis.com/auth/drive']

creds = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)

client = gspread.authorize(creds)

Открываем таблицу

sheet = client.open("Мой отчёт").sheet1

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

sheet.append_row(["Дата", "Значение"])

sheet.append_row(["2023-10-15", 42])

Подробная инструкция по настройке сервисного аккаунта: документация gspread.