Работа с данными из Microsoft Excel в Python — одна из самых востребованных задач среди аналитиков, разработчиков и специалистов по автоматизации. Несмотря на популярность CSV, формат .xlsx остаётся стандартом де-факто для хранения структурированной информации: от финансовых отчётов до логов экспериментов. Однако не все знают, что перенос данных из Excel в Python может осуществляться десятком разных способов — и выбор неподходящего метода часто приводит к ошибкам, потере форматирования или неоправданным затратам времени.
Эта статья не просто перечислит библиотеки для импорта, а поможет выбрать оптимальный инструмент под вашу задачу. Мы разберём нюансы работы с большими файлами (100+ тыс. строк), обработку формул, сохранение стилей ячеек и даже автоматизацию обновления данных. Особое внимание уделим типичным ошибкам, которые возникают при чтении файлов с объединёнными ячейками, условным форматированием или нестандартными разделителями.
Если вы ранее работали только с pandas.read_excel(), вы удивитесь, сколько возможностей скрывает openpyxl или xlrd. А для тех, кто столкнулся с ограничениями стандартных библиотек, мы покажем, как обойти их с помощью SQL-запросов к Excel или даже машинного обучения для парсинга неструктурированных таблиц.
Готовы оптимизировать свой рабочий процесс? Тогда начнём с самого простого — базового импорта данных.
1. Базовый импорт с помощью pandas: быстро и просто
Библиотека pandas — первый инструмент, к которому обращаются при работе с табличными данными в Python. Её метод read_excel() позволяет загрузить данные из Excel всего одной строкой кода, автоматически преобразуя их в удобный формат DataFrame. Это идеальное решение для большинства задач, где не требуется сохранять форматирование или работать с формулами.
Основные параметры метода:
- 📄
io— путь к файлу (например,'data.xlsx') или объект ExcelFile - 📊
sheet_name— имя листа (по умолчанию первый лист) или индекс (начиная с 0) - 🔢
header— строка с заголовками (по умолчанию 0; еслиNone— заголовков нет) - 🔍
usecols— список столбцов для импорта (например,['A', 'C']или[0, 2]) - 📅
parse_dates— автоматическое преобразование дат (например,['Дата'])
Пример минимального кода для импорта:
import pandas as pd
Чтение первого листа файла
df = pd.read_excel('отчет_2026.xlsx', sheet_name='Продажи')
Просмотр первых 5 строк
print(df.head())
Однако даже здесь есть подводные камни. Например, если в вашем файле используются объединённые ячейки, pandas просто проигнорирует их, заполнив пустыми значениями (NaN). А при работе с файлами размером более 50 МБ может возникнуть ошибка памяти — в этом случае потребуется оптимизация (об этом в разделе про большие данные).
⚠️ Внимание: При импорте файлов с русскими названиями столбцов убедитесь, что кодировка файла совпадает с кодировкой вашей системы. Иначе имена столбцов могут отобразиться как����. Решение: при сохранении в Excel выбирайте кодировкуUTF-8.
2. Работа с формулами и вычислениями: когда pandas не справляется
Один из главных недостатков pandas.read_excel() — он не вычисляет формулы в ячейках, а просто возвращает их в виде строк (например, '=SUM(A1:A10)'). Если вам нужно получить результат формулы, а не её текстовое представление, придётся использовать другие инструменты.
Для этой задачи лучше всего подходит библиотека openpyxl, которая позволяет:
- 📈 Читать значения ячеек после вычисления формул
- 🔄 Обновлять данные в файле без его открытия в Excel
- 🎨 Сохранять форматирование (цвета, шрифты, границы)
Пример кода для чтения файла с вычислением формул:
from openpyxl import load_workbook
Загружаем книгу с поддержкой формул
wb = load_workbook('отчет_с_формулами.xlsx', data_only=True)
sheet = wb['Лист1']
Чтение значения ячейки B2 (с вычисленной формулой)
value = sheet['B2'].value
print(f"Значение после вычисления: {value}")
Сохранение изменений (если нужно)
wb.save('отчет_обновленный.xlsx')
Важно: параметр data_only=True заставляет openpyxl читать последнее сохранённое значение формулы, а не её текст. Однако если файл не сохранялся после изменений в Excel, вы получите исходное значение до редактирования.
Для сложных вычислений (например, с пользовательскими функциями VBA) может потребоваться automation через pywin32, но это уже тема для отдельной статьи.
3. Оптимизация для больших файлов: как не убить память
Стандартный подход с pandas.read_excel() перестаёт работать, когда размер файла превышает 100–150 МБ. В таких случаях данные грузятся слишком долго или вовсе вызывают ошибку MemoryError. Решений несколько — от чтения файла по частям до использования специализированных библиотек.
Сравнение методов для больших файлов:
| Метод | Макс. размер файла | Скорость | Сохранение форматирования | Поддержка формул |
|---|---|---|---|---|
pandas.read_excel() |
до 100 МБ | Средняя | Нет | Нет (только текст) |
| openpyxl (построчно) | до 500 МБ | Низкая | Да | Да (с data_only) |
| xlrd (устаревший) | до 200 МБ | Высокая | Нет | Нет |
| dask.dataframe | 1+ ГБ | Очень высокая | Нет | Нет |
| SQL-запросы (sqlalchemy) | Неограничено | Высокая | Нет | Нет |
Для файлов размером 100–500 МБ оптимально использовать openpyxl в режиме построчного чтения:
from openpyxl import load_workbook
wb = load_workbook('большой_файл.xlsx', read_only=True)
sheet = wb['Data']
Чтение по строкам (экономит память)
for row in sheet.iter_rows(values_only=True):
print(row) # Каждая строка - это кортеж значений
Для файлов более 1 ГБ лучше конвертировать их в CSV прямо в Excel (через "Сохранить как") и затем читать с помощью dask или pandas с параметром chunksize:
# Чтение CSV по частям
chunk_iter = pd.read_csv('большой_файл.csv', chunksize=10000)
for chunk in chunk_iter:
process(chunk) # Обработка порции данных
⚠️ Внимание: При работе с openpyxl в режиме read_only=True вы не сможете модифицировать файл. Если нужно и читать, и записывать большие данные, разделите процесс на два этапа: сначала чтение, затем запись в новый файл.
4. Сохранение форматирования: цвета, шрифты, стили
Если вам важно не только содержимое ячеек, но и их визуальное оформление (цвет фона, жирный шрифт, границы), стандартный pandas не подойдёт — он игнорирует стили. Здесь на помощь приходят:
- 🎨 openpyxl — для чтения и записи стилей
- 🖌️ xlwings — для работы с форматами через Excel API
- 📊 styleframe — надстройка над pandas для стилизации
Пример чтения стилей с openpyxl:
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill
wb = load_workbook('стилизованный_отчет.xlsx')
sheet = wb['Data']
Чтение стиля ячейки A1
cell = sheet['A1']
print(f"Цвет фона: {cell.fill.start_color.index}") # Например, 'FFFF0000' для красного
print(f"Жирный шрифт: {cell.font.bold}")
Для применения стилей при записи данных:
# Создание нового файла со стилями
from openpyxl import Workbook
from openpyxl.styles import Font, Color
wb = Workbook()
ws = wb.active
Запись данных с форматированием
ws['A1'] = 'Прибыль'
ws['A1'].font = Font(color=Color('FF0000'), bold=True, size=14)
wb.save('отчет_со_стилями.xlsx')
Единственный способ сохранить условное форматирование при импорте в Python — использовать xlwings с запуском реального экземпляра Excel в фоне. Это требует установленного Microsoft Office на компьютере.
Для этого нужно:
1. Установить xlwings и pywin32 2. Открыть файл через COM-объект Excel 3. Скопировать правила форматирования в новый файл 4. Сохранить изменения через Excel API Этот метод работает только на Windows с установленным Office.Как сохранить условное форматирование?
5. Автоматизация: обновление данных без ручного экспорта
Если вам нужно регулярно обновлять данные из Excel в Python (например, для дашборда или отчёта), ручной экспорт становится утомительным. Решения:
- 🔄 Скрипт на Python + Task Scheduler (Windows) или cron (Linux)
- 📤 Excel Power Query + автоматическая выгрузка в
CSV/JSON - 🤖 Боты (Telegram, Slack) с триггерами на обновление файла
Пример скрипта для автоматического импорта при изменении файла:
import pandas as pd
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class ExcelHandler(FileSystemEventHandler):
def on_modified(self, event):
if event.src_path.endswith('.xlsx'):
df = pd.read_excel(event.src_path)
print("Файл обновлён! Новые данные:")
print(df.head())
Наблюдение за папкой
observer = Observer()
observer.schedule(ExcelHandler(), path='.')
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Для корпоративных систем лучше использовать ETL-инструменты (например, Apache Airflow или Prefect), которые позволяют настроить пайплайн обновления данных с логгированием и оповещениями об ошибках.
Убедиться, что путь к файлу не меняется|Проверить права на чтение/запись|Настроить обработку ошибок (например, если файл открыт в Excel)|Добавить логирование изменений|Протестировать скрипт на копии данных-->
6. Альтернативные форматы: когда Excel не подходит
Иногда данные в Excel хранятся в неудобном виде — например, в виде сводных таблиц, иерархических структур или вложенных комментариев. В таких случаях лучше конвертировать данные в другой формат перед импортом в Python.
Лучшие альтернативы:
- 🗃️
CSV— для плоских таблиц без формул - 📦
JSON— для вложенных структур (например, отчёты с группировкой) - 🗂️
Parquet— для больших данных с поддержкой схемы - 🔗
SQLite— для реляционных данных с связями между таблицами
Пример конвертации сложной таблицы в JSON через Python:
import pandas as pd
import json
Чтение Excel с мультииндексами (например, сводная таблица)
df = pd.read_excel('сводная_таблица.xlsx', header=[0, 1])
Преобразование в JSON с сохранением структуры
json_data = df.to_dict(orient='records')
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(json_data, f, ensure_ascii=False, indent=4)
Если ваш Excel-файл содержит много листов с связями (например, "Товары", "Заказы", "Клиенты"), рассмотрите экспорт в SQLite:
import sqlite3
import pandas as pd
Создание базы данных
conn = sqlite3.connect('data.db')
Экспорт каждого листа в отдельную таблицу
excel_file = 'комплексный_отчет.xlsx'
sheets = pd.ExcelFile(excel_file).sheet_names
for sheet in sheets:
df = pd.read_excel(excel_file, sheet_name=sheet)
df.to_sql(sheet, conn, if_exists='replace', index=False)
conn.close()
7. Типичные ошибки и их решения
Даже опытные разработчики сталкиваются с проблемами при импорте данных из Excel. Вот самые распространённые ошибки и способы их исправления:
| Ошибка | Причина | Решение |
|---|---|---|
XLRDError: Unsupported format |
Файл в формате .xlsx, а используется устаревшая xlrd |
Установите openpyxl или xlrd>=2.0 |
KeyError: "Sheet 'Лист1' not found" |
Опечатка в имени листа или лист скрыт | Проверьте имя через pd.ExcelFile('file.xlsx').sheet_names |
Дата отображается как число (например, 44197) |
Excel хранит даты как количество дней с 1900 года | Используйте pd.to_datetime() с параметром origin='1899-12-30' |
MemoryError при чтении большого файла |
Не хватает оперативной памяти | Читайте файл по частям (chunksize) или используйте dask |
Кириллица отображается как ��� |
Неверная кодировка при сохранении файла | Сохраните файл в Excel как UTF-8 CSV или укажите encoding='utf-8' |
Особенно коварна ошибка с датами. Например, если в Excel ячейка отформатирована как дата, но содержит текст (например, "31.12.2026"), pandas может не распознать её автоматически. В таких случаях поможет явное указание формата:
df = pd.read_excel('file.xlsx', parse_dates=['Дата'], date_parser=lambda x: pd.to_datetime(x, format='%d.%m.%Y'))
Ещё одна частая проблема — объединённые ячейки. Pandas не умеет с ними работать, поэтому данные из таких ячеек теряются. Решение — либо разделить ячейки в Excel перед экспортом, либо использовать openpyxl для ручной обработки:
from openpyxl.utils import range_boundaries
from openpyxl import load_workbook
wb = load_workbook('file.xlsx')
ws = wb.active
for merged_range in ws.merged_cells.ranges:
min_col, min_row, max_col, max_row = range_boundaries(str(merged_range))
value = ws.cell(row=min_row, column=min_col).value
for row in range(min_row, max_row + 1):
for col in range(min_col, max_col + 1):
ws.cell(row=row, column=col).value = value
Теперь можно сохранять и читать через pandas
wb.save('file_unmerged.xlsx')
FAQ: Ответы на частые вопросы
Можно ли импортировать данные из Excel в Python без установки дополнительных библиотек?
Нет, Python не имеет встроенной поддержки форматов Excel (.xls, .xlsx). Минимально потребуется установить pandas + openpyxl (или xlrd для старых форматов). Без внешних библиотек можно работать только с CSV, который Excel умеет экспортировать.
Как импортировать данные из защищённого паролем Excel-файла?
Используйте библиотеку msoffcrypto-tool для снятия защиты или укажите пароль прямо в pandas.read_excel():
df = pd.read_excel('protected.xlsx', password='your_password')
Обратите внимание: этот метод работает только для файлов с паролем на открытие, но не на редактирование.
Можно ли импортировать данные из Google Sheets так же, как из Excel?
Да, но для этого нужно использовать API Google Sheets или специальные библиотеки вроде gspread. Пример:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
# Аутентификация
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
data = sheet.get_all_records()
Это требует настройки Google Cloud Platform и получения ключа API.
Почему при импорте числа с плавающей запятой округляются?
Это происходит из-за различий в представлении чисел в Excel и Python. Excel использует 15 знаков после запятой, а Python — 53. Чтобы избежать округления, преобразуйте столбец в строку при чтении:
df = pd.read_excel('file.xlsx', converters={'Столбец': str})
Затем при необходимости конвертируйте строки обратно в числа с нужной точностью.
Как импортировать данные из Excel в Python на Mac, если нет Microsoft Office?
На Mac вы можете использовать:
- Бесплатный LibreOffice для открытия/сохранения файлов в
CSV. - Библиотеку openpyxl, которая не требует установленного Excel.
- Онлайн-конвертеры (например, CloudConvert) для преобразования
.xlsxвCSV.
Все перечисленные методы, кроме xlwings, работают без Microsoft Office.