Содержание урока · 10 разделов
- Что такое excelize: golang excel-связка из одного пакета
- xlsx изнутри: zip-архив с XML-документами
- Из чего собран xlsx
- Зачем Go работает с Excel: пять типовых задач
- Дескриптор File: память, диск и Close
- Excelize против CSV и остальных способов
- Способы генерировать таблицы из Go
- Песочница урока
- Коротко: что запомнить
- Вопросы и ответы
Сценарий, с которого начинается почти каждый такой проект: backend на Go с базой данных работает хорошо, пока бизнес не просит «то же самое, но в Excel». Бухгалтерии нужен реестр платежей за март, складу — остатки с ценами, продажникам — сводка по менеджерам с итоговой строкой внизу. Данные у вас есть, но жить они должны в файле с вкладками, жирными заголовками и формулой суммы, который открывается двойным кликом. Писать XML вручную, форматировать колонки и бороться с кодировками — путь в никуда: формат Office Open XML сложнее, чем кажется, и детали вроде числовых форматов легко сломать. Поэтому в экосистеме Go для этой работы есть готовая библиотека — excelize, и весь курс построен вокруг неё. Полный план из двадцати пяти уроков лежит на странице курса; здесь — карта местности: роли библиотеки, устройство формата и границы применимости.
Что такое excelize: golang excel-связка из одного пакета#
Excelize — библиотека на чистом Go, которая умеет создавать, читать и изменять xlsx-файлы, а заодно xlsm с макросами и шаблоны xltm и xltx. Чистый Go здесь ключевое слово: никаких обёрток над Excel, вызовов через COM-объекты или запуска LibreOffice на сервере — один пакет, один импорт, работает на Linux в контейнере так же, как на ноутбуке. Проект развивается с 2016 года, вырос из внутренней разработки компании 360 и давно стал де-факто стандартом работы с xlsx в экосистеме Go: если видите в Go-проекте зависимость для Excel-файлов, с высокой вероятностью это excelize. Внутри — работа с формулами, стилями, диаграммами, картинками, условным форматированием и закреплением областей, плюс потоковые API для файлов на миллионы строк, куда обычный режим уже не влезает по памяти. Для нас это значит простую вещь: почти любая задача из мира таблиц уже имеет готовую функцию с документацией и примером, и весь курс мы будем именно их разбирать.
Excelize не запускает Excel — она сама собирает и разбирает xlsx как обычный архив. Ни лицензий Office на проде, ни COM-объектов под Windows, ни LibreOffice headless в контейнере. Файл получается полноценный: открывается Excel, LibreOffice и таблицами Google.
xlsx изнутри: zip-архив с XML-документами#
Современный xlsx — это не бинарный формат, а zip-архив с набором XML-документов внутри, стандартизованный как Office Open XML (ECMA-376). Переименуйте любой xlsx в zip и распакуйте — увидите знакомую картину: описание книги в xl/workbook.xml, каждый лист отдельным документом в xl/worksheets, общая таблица строк в xl/sharedStrings.xml, стили в xl/styles.xml, плюс служебные части вроде [Content_Types].xml и свойств документа в docProps. Из этого следуют практические вещи. Файл можно инспектировать руками: когда что-то идёт не так, заглянуть в XML честнее, чем гадать по поведению Excel. Строки и стили хранятся отдельно от ячеек: одна и та же строка текста встречается в sharedStrings один раз, а ячейки на неё ссылаются. И числа хранятся как числа: то, что вы видите как дату, внутри — серийный номер дня, а внешность задаёт числовой формат; к этому мы вернёмся в уроках про стили и форматы, а пока достаточно общего понимания карты.
Из чего собран xlsx#
- [Content_Types].xml — каталог типов содержимого: что вообще лежит в архиве.
- xl/workbook.xml — список листов книги и их порядок.
- xl/worksheets/sheetN.xml — по одному документу на каждый лист с ячейками.
- xl/sharedStrings.xml — общая таблица строк, на которые ссылаются текстовые ячейки.
- xl/styles.xml — шрифты, заливки, границы и числовые форматы.
- docProps/core.xml и app.xml — метаданные: автор, даты, название документа.
Зачем Go работает с Excel: пять типовых задач#
Зачем Go работает с Excel — честнее отвечать задачами, которые приносят деньги. Первая и самая частая — отчёты: сервис по расписанию собирает данные из базы и складывает в файл с вкладками по периодам, который утром ждёт бухгалтерия; такой экспорт из базы мы соберём в уроке про экспорт отчёта из базы в Excel. Вторая — обмен с внешним миром: поставщики присылают прайсы в xlsx, банки — выписки, подрядчики — графики работ, и их надо разобрать в структуры Go; отдельный урок про импорт таблицы в структуры. Третья — интеграции с учётными системами: 1С и её родственники понимают xlsx лучше, чем REST API. Четвёртая — генерация документов с заполненным шаблоном: акты, накладные, спецификации. Пятая — разовые миграции: перенести данные из таблиц в систему или обратно. Заметьте закономерность: везде данные уже есть, вопрос только в форме, в которой их примет другой участник процесса — чаще всего человек с Excel на другом конце.
Первый взгляд: от NewFile до готового report.xlsx
GOpackage main
import (
"fmt"
"github.com/xuri/excelize/v2"
)
func main() {
f := excelize.NewFile()
defer f.Close()
f.SetCellValue("Sheet1", "A1", "Выручка за квартал")
f.SetCellValue("Sheet1", "B1", 1250000)
if err := f.SaveAs("report.xlsx"); err != nil {
panic(err)
}
fmt.Println("report.xlsx создан")
}Это не программа для копирования, а телепорт вперёд: весь курс в четырёх вызовах. excelize.NewFile создаёт книгу в памяти с одним листом Sheet1, SetCellValue кладёт значение в ячейку, SaveAs пишет файл на диск, Close освобождает ресурсы. Установка библиотеки и построчный разбор такого main.go — тема следующего урока, а типы значений в ячейках разберём в четвёртом.
Дескриптор File: память, диск и Close#
API excelize построен вокруг дескриптора *File — объекта, с которым вы работаете от создания до сохранения. excelize.NewFile возвращает книгу в памяти: все SetCellValue и прочие изменения живут только там, и никакой report.xlsx на диске не появится, пока вы не вызовете SaveAs. Для существующего файла есть симметричная пара — OpenFile, который читает xlsx и возвращает тот же дескриптор; дальше разницы нет, читаете вы или пишете. У дескриптора есть метод Close, и это не формальность: при открытии файла excelize распаковывает архив во временную папку, чтобы не держать всё в памяти, и Close прибирает за собой — забытый вызов оставляет мусор во временных каталогах, что особенно обидно для генератора отчётов, работающего по расписанию месяцами. Привычка из этого урока: defer f.Close() сразу после создания или открытия, ошибки сохранения — проверять, а не игнорировать. Методов у дескриптора много, но они комбинируются однообразно: лист, координата, значение — эта триада проходит через весь курс.
SaveAs не спросит подтверждения: если report.xlsx уже существует, он будет заменён без вариантов. Генерируете файлы в одну папку с уникальными именами (дата, период) — иначе сегодняшняя выгрузка молча затрёт вчерашнюю. Ошибка записи при этом возвращается вторым значением — проверяйте её.
Три сценария одной строкой
GO// отчёт: заголовок и данные по ячейкам
f.SetCellValue("Отчёт", "A1", "Товар")
f.SetCellValue("Отчёт", "B1", "Продажи")
// импорт прайса: чтение ячейки в строку
price, err := f.GetCellValue("Прайс", "B2")
// сводка: формула — Excel посчитает при открытии
f.SetCellFormula("Отчёт", "B10", "=SUM(B2:B9)")Это меню, а не программа: запись, чтение и формула — по одной строке на сценарий из предыдущего раздела. GetCellValue всегда возвращает строку, и приведение типов — отдельная техника с ловушками, ей посвящён пятый урок. Формулы задаются выражением, а вычисляет их Excel при открытии файла: подробный разбор ближе к одиннадцатому уроку.
Excelize против CSV и остальных способов#
Самый частый вопрос на старте: зачем целая библиотека, если CSV пишется fmt-ом за десять минут? Ответ в том, что CSV — не Excel. В нём нет листов, стилей, числовых форматов и формул; запятая внутри значения ломает файл, а Excel при открытии сам решает, что считать числом, — и немецкая локаль с запятой-разделителем превращает 12.5 в дату или текст. CSV остаётся отличным форматом обмена между программами, но как только файл будут открывать люди, нужен xlsx. Из Go-библиотек конкурент excelize — старый пакет tealeg/xlsx — жив, но развивается медленнее и по API громоздче. Ещё один путь — командовать установленным LibreOffice или Excel через командную строку и скрипты: работает, но тащит на сервер целый офис с лицензионными и операционными заботами.
Спорное мнение, которое я защищаю на проектировании: если файл нужен машине, а не человеку — берите CSV, а excelize оставьте для людей. Обмен между вашими же сервисами через CSV с фиксированными заголовками дешевле в отладке: дифф виден глазами, файл грузится в любой инструмент, а знание о типах лежит в схеме, а не в ячейках. Excelize включается, когда появляется человек, который открывает результат двойным кликом и ожидает вкладки, итоговые строки и внятные форматы чисел. Граница простая: файл живёт в пайплайнах между вашими сервисами — CSV; результат открывает директор — xlsx. Что excelize не умеет, тоже честно: старый бинарный формат Excel 97-2003 (.xls) не читается и не пишется — только современный OOXML; в PDF ничего не рендерится — печать остаётся заботе Excel; и формулы библиотека не вычисляет, она хранит выражение, а значение Excel считает при открытии, поэтому из только что сгенерированного файла формула вернёт не число, а её текстовое представление.
Способы генерировать таблицы из Go#
| Способ | Сильная сторона | Ограничение |
|---|---|---|
| excelize | полноценный xlsx: листы, стили, формулы, диаграммы, потоковые режимы | только современный OOXML; формулы считает Excel при открытии |
| encoding/csv | минимум кода, идеален для обмена между программами | нет листов, типов, стилей; локали Excel ломают числа |
| LibreOffice headless | конвертация любого офисного формата в любой другой | нужен установленный офис на сервере; медленно, тяжело в сопровождении |
| ручной XML | полный контроль над содержимым | формат OOXML огромен; одна неточность — Excel предлагает «восстановить книгу» |
Браузерная песочница сайта умеет только базовое подмножество Go (fmt, strings, strconv, math, sort, errors, time) и не пишет файлы на диск, поэтому код этого курса запускается локально: поставьте Go с go.dev — этого достаточно, Excel тоже не обязателен. Интерактивы в уроках тренируют чтение кода и API без запуска.
Проверка: формат xlsx
Что представляет собой xlsx-файл на диске?
Проверка: когда данные попадают на диск
Вы создали книгу через NewFile и заполнили ячейки. Когда появится файл?
Что выведет программа?
Прочитайте код и выберите, что он выведет:
f := excelize.NewFile()
f.SetCellValue("Sheet1", "A1", "привет")
fmt.Println("готово")Соберите первые вызовы
Допишите вызовы: создать книгу, закрыть дескриптор и сохранить файл.
Соберите программу целиком
Расставьте строки в порядке выполнения: создать книгу, записать значение, сохранить, обработать ошибку, закрыть, напечатать итог.
Строки
Ваша программа
Нажимайте на строки слева, чтобы собрать программу
Карточки: знакомство с excelize
Карта собрана: excelize — чистый Go без офиса на сервере, xlsx — zip с XML, а API построен на дескрипторе *File с триадой лист-ячейка-значение. Дальше по порядку: в уроке про установку excelize и первый файл соберём модуль и запишем report.xlsx руками, затем разберём листы книги и запись ячеек с типами данных в уроке про SetCellValue. К концу курса соберём полноценный генератор отчётов — итоговый проект со стилями, формулами и диаграммами. Домашнее задание — разминка перед установкой.
Песочница урока
Редактируйте код и запускайте его прямо здесь — интерпретатор работает в браузере, ничего устанавливать не нужно. За каждый запуск — +2 XP.
Запустите код, чтобы увидеть вывод.
Коротко: что запомнить
- Excelize — чистый Go без установленного Excel: xlsx собирается и разбирается как zip с XML.
- xlsx — это Office Open XML: листы, общая таблица строк, стили и метаданные в отдельных частях архива.
- Работа идёт через дескриптор *File: NewFile или OpenFile, изменения в памяти, SaveAs на диск, Close с defer.
- CSV — обмен между программами, xlsx — файлы для людей: листы, стили, формулы, форматы чисел.
- Excelize не считает формулы и не рендерит PDF, а старый .xls не поддерживается вовсе.
- SaveAs перезаписывает файл молча: уникальные имена и проверка ошибки обязательны.
Домашнее задание
Разминка без кода: возьмите любой xlsx-файл на своём компьютере, переименуйте расширение в .zip и распакуйте. Найдите внутри xl/workbook.xml с названиями листов и xl/worksheets/ с XML каждого листа. Запишите, какие части архива вы нашли, и как в них выглядит знакомая вам таблица — на следующем уроке пригодится.
Личные заметкиПусто
Вопросы и ответы по уроку
Можно ли excelize-код запускать в песочнице сайта?
Нет. Браузерный интерпретатор поддерживает только базовое подмножество Go (fmt, strings, strconv, math, sort, errors, time) и не умеет писать файлы на диск. Код курса рассчитан на локальный Go: поставьте его с go.dev — и все примеры урока выполнятся на вашей машине.
Excelize читает старый формат .xls от Excel 97-2003?
Нет. Библиотека работает с современным Office Open XML: xlsx как основной формат, плюс xlsm, xltm и xltx. Для старого бинарного .xls нужен конвертер или отдельный инструмент — курс концентрируется на xlsx, как и весь современный обмен данными.
Excelize вычисляет формулы?
Нет: библиотека хранит выражение формулы, а значение Excel вычисляет при открытии файла. Если файл сохранён Excel-ом, из него можно прочитать закешированное значение; из только что сгенерированного — пока нет. Поэтому итоговые суммы либо считает Excel, либо их заранее считает ваш Go-код.
Термины урока
Ключевые понятия из этого урока — короткие определения в глоссарии. Наведите на термин, чтобы вспомнить, откройте карточку для подробностей и ссылки на практику.
Изучайте дальше
Следующая ступень учебного пути
Фоновые задачи в Go: планировщик на robfig/cron
Курс по cron в Go: robfig/cron v3, синтаксис выражений, пояса, wrappers, конкурентность и graceful shutdown. 25 уроков с примерами и проектом.
- Собирать планировщик на robfig/cron v3 и запускать задачи по расписанию
- Читать и писать cron-выражения: пять полей, спецсимволы, @daily
- Управлять жизненным циклом: Start, Stop, Entry, Remove
- Держать часовые пояса и секундные расписания под контролем