Перейти к содержанию

192 уроков, 14 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 1 из 20 Начальный 35 мин 100 XP

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: он принимает список значений и дописывает их одной строкой в очередную свободную строку листа.

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.

save и проверка файла
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.

терминал, не 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, из базы. Логика генератора от этого не меняется ни строчкой.

Типичные ошибки новичка

ошибка: Workbook без импорта
wb = Workbook()   # класс никто не импортировал
Вывод
NameError: name 'Workbook' is not defined
Блок не запускается намеренно: он вызывает ошибку. Перед строкой NameError в настоящем traceback будут ещё служебные строки, но суть всегда в последней.

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)
Проверь себя
0 / 5

1. Что возвращает wb.active сразу после Workbook()?

2. Что делает ws.append(["Кофе", 350])?

3. Скрипт записал значения в ячейки, но файла на диске нет. Что забыли вызвать?

4. Как правильно обратиться к ячейке B2 листа ws?

5. Что физически представляет собой xlsx-файл?

Карточки терминов
Запомнено: 0 / 6
Практика

Собери прайс из трёх позиций: шапка ["Товар", "Цена"], затем Хлеб 45, Молоко 95, Сыр 520 — всё через append. Сохрани книгу в файл price-ex-l1.xlsx, выведи значение ячейки B3 и число занятых строк, затем удали файл, чтобы песочница осталась чистой.

practice.py
Вопросы и ответы по уроку

Как создать 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-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.