До этого урока мы работали с содержимым: значениями, стилями, формулами, диаграммами. Но у книги есть два слоя, которые не видны в ячейках. Первый — свойства документа: название, автор, компания, ключевые слова, описание. Они живут в отдельных частях архива xlsx, показываются в свойствах файла, в панели сведений Excel и учитываются поиском операционной системы и корпоративных дисков. Второй слой — настройки печати: область, которая уйдёт на бумагу, ориентация и размер страницы, поля, повторяющиеся строки и колонтитулы. Оба слоя часто остаются пустыми, и тогда отчёт ищется по безымянному файлу, печатается в двух пустых страницах и теряет шапку на каждом листе после первого. Настройки дешёвые: несколько вызовов при сборке — и файл ведёт себя прилично в руках человека. Разберём каждый слой с кодом, честно отметим, где настройки видят только принтер и предпросмотр, и закончим порядком доводки, который повторяется в любом генераторе отчётов.
Excelize метаданные: SetDocProps и DocProps#
Книга xlsx носит паспорт: свойства документа живут в отдельных частях архива и показываются в свойствах файла, панели сведений Excel и поиске системы. Excelize метаданные задаёт одной структурой: SetDocProps принимает DocProps с полями Title, Subject, Creator, Company, Keywords, Description, Category и LastModifiedBy — все строковые, и заполняются они из домена: название отчёта, период, система-источник. Польза не декоративная: поиску ОС и корпоративного диска проще найти файл по заголовку и ключевым словам, аудиту — понять, кто выпустил документ, пользователю — отличить сводку за март от сводки за апрель с одинаковой шапкой листа. Чтение обратно — GetDocProps: он возвращает ту же структуру, и это удобная точка для теста из урока про тесты генерации. Метаданные не шифруют и ничего не защищают: для ограничений правки есть защита листа из отдельного урока. И не кладите в Description лишнее: свойства читаются без открытия книги, это открытый текст внутри архива.
Паспорт книги
GOf.SetDocProps(&excelize.DocProps{
Title: "Отчёт о продажах за март",
Subject: "Продажи по регионам",
Creator: "report-bot",
Company: "Акме",
Keywords: "продажи, март, сводка",
Description: "Сводный отчёт по данным CRM",
Category: "отчёты",
})
props, err := f.GetDocProps()
if err != nil {
panic(err)
}
fmt.Println(props.Title, props.Creator)Свойства задаются одной структурой и читаются обратно той же функцией с префиксом Get. Название и период в Title и Keywords делают файл находимым, Creator показывает источник, а LastModifiedBy принято обновлять, если отчёт дорабатывает человек.
Откройте свойства файла в проводнике или панель сведений в Excel: заголовок, автор, компания и ключевые слова берутся из DocProps. Именно эти поля читают поиск операционной системы и корпоративных дисков, поэтому название отчёта и период стоит задавать на каждый выпуск, а не оставлять пустыми от шаблона. Пустой Title в поиске выглядит как «Книга1.xlsx» — файл теряется среди своих же собратьев.
Область печати и страница: SetPrintArea и SetPageLayout#
Настройки печати — договор о том, как файл превращается в бумагу или PDF. Область печати задаётся диапазоном: SetPrintArea объявляет, что на печать уйдёт A1:H40, а не весь лист с запасом на будущее. Ориентация и бумага — SetPageLayout с опциями: альбомная для широких таблиц, книжная для списков, код размера девять — это A4. Поля страницы — SetPageMargins: значения в дюймах, и экономия на полях вытягивает в ширину лишнюю колонку. Повтор шапки — SetPrintRows со строкой диапазона: первая строка с заголовками печатается на каждой странице, и таблица на сорок листов остаётся читаемой. Настройки печати excel хранятся в файле и не трогают данные: за границей области ячейки остаются на листе, просто не печатаются. Проверяются они предпросмотром печати в Excel или LibreOffice — код не покажет, как выглядит страница, и этот взгляд глазами стоит встроить в релизный чек-лист отчёта.
Печатный вид отчёта
GOif err := f.SetPrintArea("Отчёт", "A1:H40"); err != nil {
panic(err)
}
if err := f.SetPageLayout("Отчёт",
excelize.PageLayoutOrientation(excelize.OrientationLandscape),
excelize.PageLayoutPaperSize(9),
); err != nil {
panic(err)
}
if err := f.SetPageMargins("Отчёт", &excelize.PageMargins{
Left: 0.4, Right: 0.4, Top: 0.6, Bottom: 0.6,
}); err != nil {
panic(err)
}
if err := f.SetPrintRows("Отчёт", "1:1"); err != nil {
panic(err)
}Область печати ограничивает диапазон, ориентация и код бумаги девять задают альбомный A4, поля указываются в дюймах, а SetPrintRows повторяет первую строку с заголовками на каждой печатной странице. Каждый вызов возвращает ошибку — неверное имя листа или диапазон ловится на месте.
SetPrintArea не удаляет и не скрывает данные: всё, что за диапазоном, остаётся в файле и видно при обычном просмотре. Если часть данных не для печати, а для машины, держите её на отдельном служебном листе, а не за границей области. И проверяйте файл предпросмотром: печатный вид видит только принтер, тесты значений эти настройки не ловят, а пользователь обнаружит их отсутствие в самый неподходящий момент.
Колонтитулы: SetHeaderFooter и коды подстановки#
Колонтитулы — полосы над и под печатной областью, и в excelize они задаются структурой HeaderFooter: поля OddHeader и OddFooter для обычных страниц, отдельные поля для чётных и первой страницы при включённых флагах DifferentOddEven и DifferentFirst. Внутри строки поля размечаются секциями — слева, в центре и справа, — а дальше идут коды подстановки, которые Excel вычисляет при печати: номер страницы, количество страниц, дата, имя файла и имя листа. Рабочий минимум отчёта: слева название отчёта, справа номер страницы, внизу — количество страниц, чтобы читающий знал объём стопки. Коды работают только при печати: в ячейках листа их нет, и тестировать колонтитулы чтением значений бессмысленно — они живут в настройках листа и видны в предпросмотре. Шрифт и размер колонтитула задаются кодами внутри строки, но для отчётов обычно хватает значений по умолчанию: не украшайте колонтитулы, их задача — навигация по печатным страницам, а не дизайн.
Коды колонтитулов#
| Код | Что подставит | Пример места |
|---|---|---|
| &P | номер текущей страницы | &R&P справа вверху |
| &N | количество страниц | &R&P из &N внизу |
| &D | дата печати | &C&D в центре |
| &T | время печати | &L&T слева внизу |
| &F | имя файла | &C&F в центре колонтитула |
| &A | имя листа | &R&A справа вверху |
Зачем отчётам этот слой#
Метаданные и печать — слой для человека, который получает файл, а не для кода, который его делает. Отчёт продаж уходит менеджеру, менеджер печатает его или сохраняет в PDF через печать, и вот тут работают все настройки урока: область печати отрезает пустые хвосты, альбомная ориентация спасает широкую таблицу от разрыва на две страницы, повтор шапки держит контекст на каждом листе, а колонтитулы дают навигацию в стопке бумаги. Свойства документа работают до печати: по заголовку и ключевым словам файл находится в поиске, по автору и компании понятен источник, и это особенно ценно, когда отчётов много и они похожи друг на друга. Порядок доводки стабильный: данные и оформление, затем свойства, затем настройки печати, затем сохранение. Так файл закрывается с двух сторон: машину устраивают значения и структура, человеку — паспорт и печатный вид, и выгрузка выглядит законченным документом, а не сырой копией таблицы.
Чек-лист доводки файла#
- DocProps заполнен: название и период в Title, источник в Creator, слова для поиска в Keywords.
- SetPrintArea задан по фактической границе данных: пустые страницы исчезают.
- Ориентация и бумага выбраны под ширину таблицы: альбомная для широких, книжная для списков.
- SetPrintRows повторяет шапку на каждой странице: диапазон вроде 1:1.
- Колонтитулы дают навигацию: название, номер страницы и их количество.
- Печатный вид проверен предпросмотром Excel или LibreOffice перед выдачей.
Разметку колонтитулов можно набить рукой в песочнице: соберите строку с секциями слева, в центре и справа и кодами подстановки в обычной переменной, напечатайте через fmt и проверьте порядок секций глазами — strings и fmt в песочнице есть. Сами вызовы SetDocProps и SetPrintArea относятся к файлам и гоняются локально: песочница файлы не пишет, и об этом предупреждает честно.
Кейс про отчёт, который печатали руками. Сводка продаж на двадцать страниц печаталась из Excel каждую пятницу, и каждую пятницу менеджер жаловался: шапка есть только на первой странице, а дальше столбцы без названий; область печати не задана, и принтер выплёвывал две пустые страницы с парой ячеек; в свойствах файла стояло имя шаблона, и найти свежую сводку по названию было нельзя. Починка заняла полчаса: SetPrintArea по фактической границе данных, SetPrintRows с первой строкой, альбомная ориентация для широких колонок, DocProps с названием и периодом. Отдельно договорились, что колонтитул внизу показывает номер и количество страниц — претензии «потерялась страница» исчезли сами. Урок кейса: ни одна правка не касалась данных, но воспринимались они как починка отчёта целиком. Спорная деталь осталась в команде: кому отдавать автора в свойствах — технической учётке генератора или человеку, который запустил выгрузку; выбрали учётку с суффиксом, а LastModifiedBy отдали пользователю.
Проверка: область печати
Что делает SetPrintArea для листа?
Проверка: коды колонтитулов
Какой код подставит номер текущей страницы в колонтитул?
Что окажется в колонтитуле
Прочитайте код и выберите, что он выведет:
f := excelize.NewFile()
f.SetHeaderFooter("Sheet1", &excelize.HeaderFooter{
OddHeader: "&LЧерновик&CОтчёт&R&P",
})
buf, _ := f.WriteToBuffer()
rf, _ := excelize.OpenReader(buf)
props, _ := rf.GetDocProps()
fmt.Println(len(rows), props.Title)Соберите доводку отчёта
Допишите свойства документа, область печати, поля страницы и колонтитулы.
Соберите порядок доводки
Расставьте шаги доводки отчёта: собрать данные, задать область печати, ориентацию, колонтитул, свойства, сохранить.
Строки
Ваша программа
Нажимайте на строки слева, чтобы собрать программу
Карточки: свойства и печать
Слой для человека закрыт, и вместе с ним собрана вся карта инструментов excelize — осталась сборка целого. Свойства и печать естественнее всего встраиваются в скелет из урока про экспорт из базы, проверяются тестами структуры из урока про тесты генерации, а листы и их порядок, по которым раскладываются отчёты, разобраны в уроке про листы книги. Форматы чисел и дат в печатных колонках живут в уроке про форматы чисел. В итоговом проекте отчёт продаж соберёт всё пройденное: стили, итоги, диаграмму, свойства и печать. Домашнее задание — доведите свой отчёт до печати: область, ориентация, повтор шапки, колонтитулы и свойства — и посмотрите файл предпросмотром, как это сделает пользователь.
Песочница урока
Редактируйте код и запускайте его прямо здесь — интерпретатор работает в браузере, ничего устанавливать не нужно. За каждый запуск — +2 XP.
Запустите код, чтобы увидеть вывод.
Коротко: что запомнить
- DocProps — паспорт книги: Title, Creator, Company, Keywords видны в свойствах файла и поиске ОС.
- GetDocProps читает свойства обратно: удобная точка для теста генерации.
- SetPrintArea задаёт печатный диапазон, данные за границей остаются в файле.
- SetPageLayout и SetPageMargins отвечают за ориентацию, бумагу и поля в дюймах.
- SetPrintRows повторяет шапку на каждой странице, колонтитулы дают номера и даты.
- Печатный вид проверяется предпросмотром Excel: код не показывает вид страницы.
Домашнее задание
Доведите свой отчёт до печатного вида: задайте DocProps с названием и периодом, область печати по фактической границе данных, альбомную ориентацию для широких таблиц и повтор первой строки. Добавьте колонтитулы с названием слева и номерами страниц справа. Откройте предпросмотр печати в Excel или LibreOffice и проверьте, что таблица не рвётся по колонкам, а пустые страницы исчезли. В тесты добавьте проверку GetDocProps на название и автора.
Личные заметкиПусто
Вопросы и ответы по уроку
Настройки печати не видны в файле — где их проверить?
В предпросмотре печати Excel или LibreOffice: область, ориентация, поля, повтор шапки и колонтитулы проявляются только там. Часть настроек читается программно функциями Get, но печатный вид честнее смотреть глазами перед выдачей.
Можно ли защитить метаданные от изменения?
Свойства документа — открытый текст внутри архива, ограничений правки на них не ставится. Если источник важен, подписывайте файл вне excelize или храните контрольную сумму рядом: внутри книги метаданные остаются справкой, а не защитой.
Почему поля страницы в дюймах, а не в сантиметрах?
Формат xlsx хранит поля в дюймах, и excelize передаёт значения как есть. Переведите сантиметры в дюймы в одном месте кода и держите константы рядом с настройками печати, чтобы значения не расползались по генератору.
Термины урока
Ключевые понятия из этого урока — короткие определения в глоссарии. Наведите на термин, чтобы вспомнить, откройте карточку для подробностей и ссылки на практику.
Изучайте дальше
Следующая ступень учебного пути
Фоновые задачи в Go: планировщик на robfig/cron
Курс по cron в Go: robfig/cron v3, синтаксис выражений, пояса, wrappers, конкурентность и graceful shutdown. 25 уроков с примерами и проектом.
- Собирать планировщик на robfig/cron v3 и запускать задачи по расписанию
- Читать и писать cron-выражения: пять полей, спецсимволы, @daily
- Управлять жизненным циклом: Start, Stop, Entry, Remove
- Держать часовые пояса и секундные расписания под контролем