Excel на Python: первая книга xlsx через openpyxl
Первая книга xlsx из кода: Workbook, запись в ячейки и wb.save — настоящий Excel-файл создаётся прямо в браузере, без установленного Excel.
Редакция Питоники
Прайс на завтра, тот же прайс с новыми ценами в пятницу — и всё руками: выделить шапку, залить синим, протянуть границы, проверить, что ничего не съехало. Час в Excel, и уже хочется, чтобы эту работу делал кто-то другой. Пусть её делает Python: библиотека openpyxl собирает настоящие xlsx-файлы из кода — с листами, ячейками и теми данными, которые ты ей передашь. Один раз написал скрипт — и дальше прайс генерируется за секунды, хоть на сотню позиций, хоть на тысячу.
В первом уроке пройдём весь путь целиком: создадим книгу, запишем значения в ячейки и сохраним файл. Файл получится настоящий — его можно открыть в Excel, Google Таблицах или LibreOffice.
Что такое openpyxl и почему он не требует Excel
openpyxl — библиотека Python для чтения и записи файлов Excel формата xlsx. Секрет формата не так страшен, как кажется: xlsx — это обычный zip-архив, внутри которого лежат XML-файлы с таблицей. openpyxl собирает этот архив сама. Microsoft Office не нужен вообще: ни лицензии, ни установленного Excel, ни Windows — openpyxl написан на чистом Python и работает везде, где работает сам Python.
Именно поэтому весь курс устроен так: код исполняется прямо на странице, в браузерном интерпретаторе, а создаваемые файлы — настоящие. Библиотека сидит и под капотом у pandas: read_excel в итоге тоже обращается к openpyxl. Разница в уровне управления: pandas работает с таблицей данных целиком, а openpyxl — с каждым листом, ячейкой и стилем.
- создавать книги и листы, писать в ячейки текст, числа и даты;
- форматировать: шрифты, заливки, границы, объединение ячеек;
- читать готовые файлы и обходить их данные циклом;
- строить диаграммы, «умные» таблицы и выпадающие списки.
Оговорка для честности: openpyxl работает только с новыми форматами — xlsx и xlsm (с макросами). Старые файлы Excel 97-2003 с расширением .xls она ни читает, ни пишет: закрытый бинарный формат, и разбирать его openpyxl не берётся. Попадётся такой файл — открой его в Excel или LibreOffice и пересохрани в xlsx, дальше всё применимо без оговорок. Ещё одно следствие чистого Python: установка весит немного, зависимостей почти нет, и ничего из пакета не требует прав администратора.
Как запускать код из этого урока
У каждого код-блока на странице есть кнопка «Запустить». Код выполняется в полноценном интерпретаторе Python внутри браузера (проект Pyodide), а openpyxl ставится в эту песочницу автоматически при первом же импорте — ничего устанавливать не нужно. Пишешь from openpyxl import Workbook — библиотека уже на месте.
from openpyxl import Workbook
import os
wb = Workbook() # новая пустая книга
ws = wb.active # единственный лист, он же активный
ws["A1"] = "Товар"
ws["B1"] = "Цена"
wb.save("price-l1.xlsx")
print("Лист:", ws.title)
print("Файл создан:", os.path.exists("price-l1.xlsx"))
os.remove("price-l1.xlsx")
Лист: Sheet Файл создан: True
Пять строк — и Excel-файл существует. Разбираем по шагам. Workbook() создаёт новую книгу: пустую, с единственным листом. wb.active возвращает этот лист — ссылку, через которую мы дальше работаем с ячейками. Запись ws["A1"] = "Товар" кладёт значение в ячейку по адресу: буква столбца, номер строки. wb.save("price-l1.xlsx") записывает книгу в файл. Имя листа по умолчанию — Sheet, и его можно менять: листами займёмся в уроке 2.
Как записать несколько ячеек
Ячейка — это объект, а её содержимое доступно через .value — подробно о ячейках и типах значений поговорим в уроке 3. Пока достаточно факта: записал значение — можешь тут же прочитать его обратно той же квадратной скобкой.
from openpyxl import Workbook
import os
wb = Workbook()
ws = wb.active
ws["A1"] = "Модель"
ws["B1"] = "Память"
ws["A2"] = "Байкал-1"
ws["B2"] = 64
for addr in ("A1", "B1", "A2", "B2"):
print(addr, "->", ws[addr].value)
wb.save("price-l1.xlsx")
os.remove("price-l1.xlsx")
A1 -> Модель B1 -> Память A2 -> Байкал-1 B2 -> 64
Обрати внимание: 64 записалось как число, без кавычек — openpyxl хранит тип значения, а не превращает всё в текст. Для таблиц, где строки данных идут подряд, есть путь покороче — метод append: он принимает список значений и дописывает их одной строкой в очередную свободную строку листа.
from openpyxl import Workbook
import os
wb = Workbook()
ws = wb.active
ws.append(["Товар", "Цена"]) # первая строка - шапка
ws.append(["Кофе", 350])
ws.append(["Чай", 120])
ws.append(["Какао", 280])
print("Строк:", ws.max_row)
print("A3:", ws["A3"].value, "-", ws["B3"].value, "руб.")
wb.save("price-l1.xlsx")
os.remove("price-l1.xlsx")
Строк: 4 A3: Чай - 120 руб.
Первый append создал шапку в первой строке — метод всегда начинает с первой свободной. Дальше каждая строка данных легла под предыдущей. ws.max_row вернул номер последней занятой строки: четыре append-вызова — четыре строки. Когда использовать что: адреса — если место каждого значения известно заранее (шапка, итоги), append — если данные приходят списком строк, например из другого файла или API.
| Шаг | Команда | Что происходит |
|---|---|---|
| Подключить | from openpyxl import Workbook | библиотека на месте — в песочнице ставится сама |
| Создать | wb = Workbook() | новая книга с одним листом Sheet |
| Наполнить | ws["A1"] = ... / ws.append(...) | значения попадают в ячейки — пока в памяти |
| Сохранить | wb.save("файл.xlsx") | книга записывается в настоящий xlsx-файл |
Эта четвёрка — скелет любого скрипта генерации Excel, от учебного примера до отчёта на десять тысяч строк. Меняется только средний шаг: чем сложнее данные, тем больше кода между созданием книги и сохранением. Первая и последняя строки остаются одинаковыми почти всегда.
Как сохранить книгу: wb.save
Записи в ячейки живут в памяти — пока wb.save не вызван, на диске ничего нет. Проверим честно, средствами стандартной библиотеки os.path.
from openpyxl import Workbook
import os
wb = Workbook()
ws = wb.active
ws["A1"] = "xlsx - это zip-архив с XML внутри"
wb.save("price-l1.xlsx")
size = os.path.getsize("price-l1.xlsx")
print("Файл на диске:", os.path.exists("price-l1.xlsx"))
print("В файле есть данные:", size > 0)
os.remove("price-l1.xlsx")
print("После удаления:", os.path.exists("price-l1.xlsx"))
Файл на диске: True В файле есть данные: True После удаления: False
from openpyxl import Workbook
import os
wb = Workbook()
ws = wb.active
ws["A1"] = "записали, но не сохранили"
print("Файл существует:", os.path.exists("demo-l1.xlsx"))
Файл существует: False
Ячейка наполнена, ошибки никакого нет — а файла не существует. Такие баги коварны: скрипт отрабатывает молча и «успешно», а пустой результат обнаруживается позже, когда файл ищет человек. os.path.exists сразу после save — дешёвая страховка для любого генератора отчётов.
Что если файл уже существует?
Пока мы создавали книги с нуля, но частый сценарий другой: файл есть, и в него нужно дописать или поправить. Для этого openpyxl открывает готовый файл и возвращает его как книгу — дальше те же квадратные скобки, тот же save. Заглянем на минуту вперёд, чтобы ты увидел: перезапись существующего файла выглядит как создание, только вместо Workbook() — открытие.
from openpyxl import Workbook, load_workbook
import os
wb = Workbook()
ws = wb.active
ws["A1"] = "старая цена"
wb.save("price-l1.xlsx")
book = load_workbook("price-l1.xlsx") # открыли готовый файл
book.active["A1"] = "новая цена"
book.save("price-l1.xlsx") # и перезаписали
check = load_workbook("price-l1.xlsx")
print(check.active["A1"].value)
os.remove("price-l1.xlsx")
новая цена
Функция load_workbook открывает файл по имени, правки ложатся в книгу в памяти, а save записывает её обратно под тем же именем. Не пугайся двух лишних строк с повторным чтением — они здесь только для проверки: третий раз открываем файл и убеждаемся, что на диске теперь «новая цена». Полноценно чтением готовых файлов займёмся в уроке 4, там и разберём обход данных циклом.
Установка openpyxl на своём компьютере
На этой странице openpyxl уже установлен. Однажды ты захочешь повторить то же самое в PyCharm или своём скрипте — стандартный путь через pip. Команды выполняются в терминале, а не внутри Python.
pip install openpyxl
python -c "import openpyxl; print(openpyxl.__version__)"
Successfully installed openpyxl-3.1.5
Внутри виртуального окружения ставь через python -m pip install openpyxl — так пакет гарантированно попадёт в нужный интерпретатор. Ошибка ModuleNotFoundError: No module named 'openpyxl' почти всегда означает, что пакет установлен в один Python, а запускается другой. Заодно посмотрим, что лежит внутри новой книги.
from openpyxl import Workbook
wb = Workbook()
print(wb.sheetnames) # имена всех листов книги
print(wb.active.title) # имя активного листа
['Sheet'] Sheet
Книга — это контейнер с листами, sheetnames — их имена, и в новой книге он ровно один. Добавлять, переименовывать, переставлять и удалять листы — тема следующего урока, а сейчас соберём всё изученное в цельную программу.
Первая программа: прайс-лист
from openpyxl import Workbook
import os
wb = Workbook()
ws = wb.active
ws.title = "Прайс" # переименуем лист (подробно - в уроке 2)
ws.append(["Товар", "Цена, руб."])
for row in [["Кофе", 350], ["Чай", 120], ["Какао", 280], ["Сироп", 90]]:
ws.append(row)
wb.save("price-l1.xlsx")
print("Листов в книге:", len(wb.sheetnames))
print("Строк на листе:", ws.max_row)
print("B5:", ws["B5"].value)
os.remove("price-l1.xlsx")
Листов в книге: 1 Строк на листе: 5 B5: 90
Шапка легла в первую строку, четыре позиции заняли строки со второй по пятую, и B5 вернул цену последнего товара. Данные в примере захардкожены для простоты, но они могут прийти откуда угодно: из списка словарей, из ответа API, из базы. Логика генератора от этого не меняется ни строчкой.
Типичные ошибки новичка
wb = Workbook() # класс никто не импортировал
NameError: name 'Workbook' is not defined
NameError: name 'Workbook' is not defined — импорта нет или он написан иначе. Лечится первой строкой from openpyxl import Workbook. Вторая по частоте ошибка — сохранить файл не с тем расширением: price.xls openpyxl запишет, но это будет xlsx-содержимое под старым именем, и Excel откажется его открывать. Третья — забыть save, и её мы уже разобрали: без сохранения файла не существует.
Что дальше
Ты собрал первую настоящую книгу: импорт, активный лист, запись по адресам и через append, сохранение и проверка файла. Дальше по курсу: листы — создание, переименование и выбор; ячейки — адреса, значения и типы данных; затем форматирование, от которого прайс перестанет выглядеть самодельным. К пятому уроку тот самый ручной час в Excel сожмётся в один запуск скрипта.
xlsx — это zip-архив с XML внутри: openpyxl собирает его сама, без установленного Excel.
Сначала предскажи ответ в голове — это главный навык программиста.
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws["A1"] = 40
ws["A2"] = ws["A1"].value + 2
print(ws["A2"].value)
print(wb.sheetnames)
from openpyxl import Workbook
import os
wb = Workbook()
ws = wb.active
ws["A1"] = "привет"
print("Файл существует:", os.path.exists("demo.xlsx"))
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.append(["A", "B"])
ws.append([1, 2])
print(ws["B2"].value, ws.max_row)
1. Что возвращает wb.active сразу после Workbook()?
2. Что делает ws.append(["Кофе", 350])?
3. Скрипт записал значения в ячейки, но файла на диске нет. Что забыли вызвать?
4. Как правильно обратиться к ячейке B2 листа ws?
5. Что физически представляет собой xlsx-файл?
Собери прайс из трёх позиций: шапка ["Товар", "Цена"], затем Хлеб 45, Молоко 95, Сыр 520 — всё через append. Сохрани книгу в файл price-ex-l1.xlsx, выведи значение ячейки B3 и число занятых строк, затем удали файл, чтобы песочница осталась чистой.
Как создать Excel-файл через Python?
Установи openpyxl (pip install openpyxl), создай книгу командой wb = Workbook(), запиши значения в ячейки активного листа через ws["A1"] = ... или ws.append([...]) и сохрани файл: wb.save("файл.xlsx"). На этой странице всё это можно сделать прямо в браузере — openpyxl ставится в песочницу автоматически.
Нужен ли установленный Excel, чтобы работать с openpyxl?
Нет. openpyxl написана на чистом Python и сама собирает xlsx-файл — а он устроен как zip-архив с XML внутри. Ни Microsoft Office, ни лицензии, ни Windows не требуются: файлы создаются даже в браузерном интерпретаторе, а открываются потом в Excel, Google Таблицах или LibreOffice.
Куда сохранился файл после wb.save?
В папку, из которой запущен скрипт, если имя было относительным («price.xlsx»), либо по указанному пути. В браузерной песочнице этой страницы файл попадает в виртуальную файловую систему в памяти вкладки — он настоящий, но живёт только внутри страницы. Проверить создание помогает os.path.exists.
Чем xlsx отличается от старого xls?
xls — закрытый бинарный формат Excel 97-2003, xlsx — открытый zip-контейнер с XML, стандарт с Office 2007. openpyxl работает только с xlsx и xlsm: читать и писать xls она не умеет. Если попался старый файл — сначала пересохрани его в xlsx вручную, дальше весь курс применим без оговорок.
Понравился урок? Сошлитесь на него
«Ошибка новичка номер один: записать всё в ячейки и не вызвать wb.save — пока save не выполнен, книги на диске нет.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что читать дальше
openpyxl · Урок 2
Листы в openpyxl: создание, переименование и выбор листа
Книга с одним листом — это заметка. Строим настоящую книгу: create_sheet с позицией, переименование, выбор по имени, удаление и цветные ярлычки.
openpyxl · Урок 3
Ячейки в openpyxl: адреса, значения и типы данных
Два способа попасть в ячейку: по адресу и по координатам. Числа против строк, ловушка «2026 как текст», очистка через None и чтение значений обратно.
Pandas · Урок 2
Чтение файлов в Pandas: read_csv, read_excel и знакомство с данными
read_csv со всеми нужными параметрами и примерами: разделители, кодировки с кириллицей, чтение куска большого файла и первые ошибки, которые вы увидите на практике.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
json · Урок 4
Файлы JSON: json.dump и json.load
Данные, которые переживают скрипт: json.dump пишет словарь в файл, json.load читает обратно, а round-trip подтверждает — сохранил, прочитал, совпало.
json файл python сохранитьсохранить словарь в файл python
Pandas · Урок 1
Что такое Pandas и как установить через pip: первые Series и DataFrame
Первая таблица DataFrame в библиотеке pandas, умный столбец Series и быстрый осмотр данных через head, info и describe — старт сквозного анализа данных интернет-магазина.
pandas для начинающихpandas или excel
openpyxl · Урок 10
Формулы в openpyxl: записываем, но не считаем
Ячейка со строкой «=SUM(B2:B10)» — это настоящая формула Excel: openpyxl сохранит её в файл, но считать не будет — вычисления случатся, когда файл откроет Excel.
openpyxl формулыopenpyxl формула в ячейке