Как открыть файл Excel в Python с помощью Pandas: полное руководство с примерами

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

Работа с данными из Microsoft Excel в Python стала неотъемлемой частью анализа данных, автоматизации отчётности и машинного обучения. Библиотека Pandas предоставляет мощные инструменты для чтения, обработки и записи табличных данных, но многие пользователи сталкиваются с трудностями уже на этапе загрузки файла. Почему? Потому что Excel — это не просто таблица, а сложный формат с листами, формулами, стилями и скрытыми данными.

В этой статье вы узнаете не только базовые команды типа pd.read_excel(), но и нюансы работы с разными версиями файлов (.xls vs .xlsx), обработку ошибок при повреждённых данных, оптимизацию памяти для больших файлов и даже автоматизацию обработки нескольких листов. Мы разберём реальные кейсы: от простого импорта до парсинга данных с формулами и макросами. Готовы превратить хаос Excel в структурированные DataFrame?

1. Установка необходимых библиотек

Прежде чем открывать Excel-файлы, убедитесь, что у вас установлены все требуемые пакеты. Pandas — это основа, но для работы с Excel понадобятся дополнительные зависимости:

  • 📦 pandas — основная библиотека для работы с данными (уже включает базовую поддержку Excel через openpyxl и xlrd).
  • 📦 openpyxl — для работы с форматом .xlsx (Excel 2007 и новее).
  • 📦 xlrd — для устаревших форматов .xls (Excel 97-2003). С 2023 года xlrd больше не поддерживает .xlsx, поэтому для новых файлов используйте openpyxl!
  • 📦 odfpy — если вам нужно работать с .ods (OpenDocument Spreadsheet).

Установите их одной командой в терминале:

pip install pandas openpyxl xlrd odfpy
⚠️ Внимание: Если вы используете Anaconda, некоторые пакеты могут конфликтовать. В этом случае создайте отдельное окружение:
conda create -n excel_env python=3.10 pandas openpyxl

conda activate excel_env

После установки проверьте версии библиотек, чтобы избежать ошибок совместимости:

import pandas as pd

import openpyxl

import xlrd

print(f"Pandas: {pd.__version__}")

print(f"OpenPyXL: {openpyxl.__version__}")

print(f"XLRD: {xlrd.__version__}")

📊 Какой менеджер пакетов вы используете?
pip
conda
poetry
другое

2. Базовый синтаксис: как прочитать Excel-файл в DataFrame

Самый простой способ загрузить данные из Excel — использовать функцию pd.read_excel(). Она автоматически преобразует листы Excel в объекты DataFrame, которые удобно анализировать. Рассмотрим минимальный рабочий пример:

import pandas as pd

Загрузка файла (указываем путь к файлу)

df = pd.read_excel("data.xlsx")

Просмотр первых 5 строк

print(df.head())

Но что делать, если:

  • 📂 Файл находится в другой папке? Укажите полный путь: pd.read_excel("C:/Users/YourName/Documents/data.xlsx").
  • 📄 В файле несколько листов? Используйте параметр sheet_name (подробнее в следующем разделе).
  • 🔢 Нужно прочитать только часть данных? Задайте nrows=100 для первых 100 строк или usecols="A:C" для столбцов A-C.
⚠️ Внимание: Если в ячейках Excel есть объединённые ячейки, Pandas заполнит их значением только первой ячейки, а остальные оставит пустыми (NaN). Чтобы избежать этого, предварительно разъедините ячейки в самом Excel.

Пример с дополнительными параметрами:

df = pd.read_excel(

"sales_report.xlsx",

sheet_name="2023", # имя листа

header=2, # использовать 3-ю строку как заголовок

skiprows=1, # пропустить первую строку

dtype={"ID": str} # привести столбец ID к строковому типу

)

3. Работа с несколькими листами

Один из самых частых вопросов: "Как прочитать все листы Excel в отдельные DataFrame?" Pandas предлагает несколько подходов:

Способ 1: Загрузка всех листов в словарь

all_sheets = pd.read_excel("multi_sheets.xlsx", sheet_name=None)

Теперь all_sheets — это словарь, где ключи — имена листов, значения — DataFrame

for sheet_name, df in all_sheets.items():

print(f"Лист: {sheet_name}, строк: {len(df)}")

Способ 2: Чтение конкретных листов

# Загрузить только листы "Jan" и "Feb"

selected_sheets = pd.read_excel("monthly_data.xlsx", sheet_name=["Jan", "Feb"])

Способ 3: Динамическая обработка листов

Если имена листов следуют шаблону (например, "2023_Q1", "2023_Q2"), можно использовать регулярные выражения:

import re

all_sheets = pd.read_excel("quarterly.xlsx", sheet_name=None)

quarterly_data = {k: v for k, v in all_sheets.items() if re.match(r"2023_Q\d", k)}

Параметр Описание Пример
sheet_name Имя листа (или список имён). Если None — загружает все листы в словарь. sheet_name="Sales" или sheet_name=[0, 2] (индексы листов)
skiprows Пропустить указанное количество строк сверху. skiprows=3
header Номер строки для использования как заголовка (или None, если заголовков нет). header=1
usecols Список столбцов для чтения (индексы или буквы). usecols="A,C:E"

Убедиться, что все листы имеют уникальные имена|

Проверить отсутствие объединённых ячеек в заголовках|

Удалить пустые строки/столбцы на границах данных|

Преобразовать формулы в значения (Ctrl+Shift+Enter в Excel)|

Сохранить файл в формате .xlsx (не .xls) для лучшей совместимости-->

4. Обработка ошибок и "грязных" данных

Реальные Excel-файлы редко бывают идеальными. Вот типичные проблемы и их решения:

Проблема 1: Повреждённые файлы

Если Pandas выдаёт ошибку XLRDError: Unsupported format, or corrupt file, попробуйте:

  • 🔧 Открыть файл в Excel и сохранить заново (иногда помогает "Сохранить как...").
  • 🔧 Использовать параметр engine="openpyxl" для .xlsx:
df = pd.read_excel("corrupted.xlsx", engine="openpyxl")

Проблема 2: Разные типы данных в одном столбце

Excel может хранить в одном столбце и числа, и текст (например, "100" и "Н/Д"). Pandas по умолчанию преобразует такой столбец в object (строку). Чтобы контролировать типы:

df = pd.read_excel(

"mixed_data.xlsx",

dtype={"Column1": str, "Column2": float}, # явное указание типов

converters={"Column3": lambda x: str(x).strip()} # кастомный конвертер

)

Проблема 3: Даты в нестандартном формате

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

df = pd.read_excel(

"dates.xlsx",

parse_dates=["DateColumn"], # преобразовать в datetime

date_parser=lambda x: pd.to_datetime(x, format="%d.%m.%Y") # кастомный парсер

)

⚠️ Внимание: Если в Excel используются формулы, Pandas прочитает только их текущие значения, а не сами формулы. Чтобы получить формулы, используйте библиотеку openpyxl напрямую:
from openpyxl import load_workbook

wb = load_workbook("formulas.xlsx", data_only=False)

ws = wb.active

print(ws["A1"].value) # вернёт формулу, например "=SUM(B1:B10)"

Как обработать файлы с макросами (.xlsm)?

Pandas не поддерживает выполнение макросов, но вы можете:

1. Открыть файл в Excel и сохранить как .xlsx (без макросов).

2. Использовать xlwings для автоматизации макросов перед чтением в Pandas:

import xlwings as xw

wb = xw.Book("macro_file.xlsm")

wb.macro("MyMacro")() # выполнить макрос

wb.save("output.xlsx") # сохранить результаты

wb.close()

df = pd.read_excel("output.xlsx")

5. Оптимизация производительности для больших файлов

Если ваш Excel-файл весит сотни мегабайт, стандартный pd.read_excel() может работать слишком долго или вообще упасть с ошибкой памяти. Вот как ускорить процесс:

Способ 1: Чтение по частям (chunking)

Аналогично pd.read_csv(chunksize=...), для Excel можно использовать openpyxl в ручном режиме:

from openpyxl import load_workbook

wb = load_workbook("huge_file.xlsx", read_only=True)

ws = wb.active

Читаем данные порциями

for row in ws.iter_rows(values_only=True, min_row=2, max_row=10000):

process_row(row) # ваша функция обработки

Способ 2: Указание типов данных заранее

Pandas тратит много времени на выведение типов. Явное указание dtype ускоряет процесс:

dtypes = {

"ID": "int32",

"Name": "category",

"Value": "float32"

}

df = pd.read_excel("big_data.xlsx", dtype=dtypes)

Способ 3: Использование альтернативных движков

Для .xlsx openpyxl работает быстрее xlrd, а для .xls — наоборот. Сравните:

# Для .xlsx

df = pd.read_excel("large.xlsx", engine="openpyxl")

Для .xls

df = pd.read_excel("old.xls", engine="xlrd")

Метод Когда использовать Примерный выигрыш в скорости
Чтение по частям (read_only=True) Файлы > 500 МБ до 10 раз
Явное указание dtype Файлы с однотипными данными до 3 раз
Отключение парсинга дат (parse_dates=False) Если даты не нужны до 2 раз

6. Продвинутые техники: формулы, стили и автоматизация

Pandas умеет не только читать данные, но и взаимодействовать с более сложными элементами Excel.

Работа с формулами

Какmentioned ранее, Pandas не вычисляет формулы — он берёт их текущие значения. Но вы можете:

  • 📊 Использовать openpyxl для извлечения формул:
  • 📊 Пересчитать формулы в Excel и сохранить значения:
# В Excel: выделите данные → Копировать → Специальная вставка → Значения

Затем сохраните файл и загрузите в Pandas

Извлечение стилей и форматирования

Если вам нужны не только данные, но и их стили (цвет ячейки, шрифт и т.д.), используйте:

from openpyxl import load_workbook

from openpyxl.styles import PatternFill, Font

wb = load_workbook("styled.xlsx")

ws = wb.active

for row in ws.iter_rows(min_row=1, max_row=5):

for cell in row:

print(f"Значение: {cell.value}, Цвет фона: {cell.fill.start_color.index}")

Автоматизация обработки множества файлов

Допустим, у вас папка с 100 Excel-файлами, которые нужно объединить. Вот как это сделать:

import os

import glob

Получаем все файлы .xlsx в папке

file_list = glob.glob("reports/*.xlsx")

Чтение и объединение

dfs = []

for file in file_list:

df = pd.read_excel(file)

dfs.append(df)

combined_df = pd.concat(dfs, ignore_index=True)

7. Экспорт данных обратно в Excel

После обработки данных в Pandas часто требуется сохранить результаты обратно в Excel. Базовый синтаксис:

df.to_excel("output.xlsx", index=False, sheet_name="Results")

Но что если нужно:

  • 📑 Сохранить несколько DataFrame на разных листах?
  • 🎨 Сохранить форматирование (цвета, шрифты)?
  • 🔒 Защитить лист паролем?

Сохранение нескольких листов

with pd.ExcelWriter("multi_output.xlsx", engine="openpyxl") as writer:

df1.to_excel(writer, sheet_name="Sheet1", index=False)

df2.to_excel(writer, sheet_name="Sheet2", index=False)

df3.to_excel(writer, sheet_name="Sheet3", index=False)

Добавление форматирования

Используйте openpyxl для стилизации после сохранения:

from openpyxl import load_workbook

from openpyxl.styles import PatternFill, Font

Сохраняем данные

df.to_excel("styled_output.xlsx", index=False)

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

wb = load_workbook("styled_output.xlsx")

ws = wb.active

Красим заголовки

for cell in ws[1]:

cell.font = Font(bold=True, color="0000FF")

cell.fill = PatternFill(start_color="DDDDDD", fill_type="solid")

wb.save("styled_output.xlsx")

⚠️ Внимание: При сохранении в Excel через Pandas теряются:
  • 📌 Объединённые ячейки (их нужно настраивать отдельно через openpyxl).
  • 📌 Условное форматирование.
  • 📌 Вложенные таблицы и сводные таблицы (их нужно создавать заново).

Если эти элементы критичны, рассмотрите генерацию отчётов в Jupyter Notebook с последующим экспортом в PDF.

8. Альтернативные библиотеки для работы с Excel

Pandas — не единственный инструмент для работы с Excel в Python. Рассмотрим альтернативы для специфических задач:

Библиотека Когда использовать Пример кода
openpyxl Низкоуровневая работа с .xlsx (стили, формулы, диаграммы).
from openpyxl import Workbook

wb = Workbook()

ws = wb.active

ws["A1"] = "Hello"

wb.save("hello.xlsx")

xlwings Автоматизация Excel через COM (Windows/macOS), работа с макросами.
import xlwings as xw

wb = xw.Book("report.xlsm")

wb.macro("UpdateData")()

wb.save()

pyxlsb Чтение бинарных файлов Excel (.xlsb).
from pyxlsb import open_workbook

with open_workbook("large.xlsb") as wb:

with wb.get_sheet(1) as sheet:

for row in sheet.rows():

print(row)

pandas + SQL Для аналитики больших данных (экспорт в базу и обратно).
df.to_sql("table", con=engine)

df = pd.read_sql("SELECT * FROM table", con=engine)

Выбор библиотеки зависит от задачи:

  • 📈 Для анализа данных → Pandas.
  • 🎨 Для создания красивых отчётов → openpyxl + Jinja2 для шаблонов.
  • 🤖 Для автоматизации рутинных задач → xlwings.
  • 🗃️ Для работы с огромными файлами → Dask или Modin (альтернативы Pandas).

FAQ: Частые вопросы и ответы

Можно ли открыть Excel-файл напрямую из Google Sheets или облака?

Да, но не через Pandas напрямую. Сначала скачайте файл:

# Для Google Sheets

from pygsheets import authorize

gc = authorize(service_file='credentials.json')

sh = gc.open("My Sheet")

ws = sh[0]

df = ws.get_as_df()

Для облачных хранилищ (например, S3)

import boto3

s3 = boto3.client('s3')

s3.download_file('my-bucket', 'data.xlsx', 'local.xlsx')

df = pd.read_excel('local.xlsx')

Почему Pandas неправильно считывает даты (например, "44197" вместо "01.01.2021")?

Excel хранит даты как количество дней с 1900 года. Используйте pd.to_datetime() с указанием начала отсчёта:

df["Date"] = pd.to_datetime(df["Date"], origin="1899-12-30", unit="D")

Для дат в текстовом формате укажите format:

df["Date"] = pd.to_datetime(df["Date"], format="%d.%m.%Y")
Как обработать файл Excel, который обновляется в реальном времени?

Используйте watchdog для отслеживания изменений файла и перезагрузки данных:

from watchdog.observers import Observer

from watchdog.events import FileSystemEventHandler

class ExcelHandler(FileSystemEventHandler):

def on_modified(self, event):

if event.src_path.endswith(".xlsx"):

global df

df = pd.read_excel(event.src_path)

print("Данные обновлены!")

observer = Observer()

observer.schedule(ExcelHandler(), path=".")

observer.start()

Можно ли открыть Excel-файл без установленного Microsoft Office?

Да, все перечисленные библиотеки (pandas, openpyxl, xlrd) работают независимо от Excel. Они используют собственные парсеры для чтения форматов .xlsx/.xls.

Исключение: xlwings требует установленного Excel на Windows/macOS, так как взаимодействует с приложением через COM.

Как ускорить чтение файла с 1 миллионом строк?

Комбинация методов:

  1. Используйте engine="openpyxl" и read_only=True.
  2. Читайте только нужные столбцы: usecols=["Column1", "Column2"].
  3. Укажите типы данных заранее: dtype={"ID": "int32"}.
  4. Отключите парсинг дат: parse_dates=False.
  5. Читайте файл порциями (см. раздел про оптимизацию).

Пример:

df = pd.read_excel(

"huge.xlsx",

engine="openpyxl",

read_only=True,

usecols="A:C,E:G",

dtype={"ID": "int32", "Value": "float32"},

parse_dates=False

)