Перейти к содержимому
ГоМастер

Поиск по урокам

Найдите урок, курс, термин или раздел

Урок 10 из 25 ~16 мин +20 XP

Слияние и ширина: MergeCell и SetColWidth

Запрос excelize mergecell приходит с двумя классическими жалобами: заголовок «Отчёт за квартал» торчит из одной ячейки, обрезанный соседями, а в колонке дат вместо чисел — решётки. Обе жалобы лечатся размерами листа: слияние собирает шапку в один блок, ширина столбцов excelize отдаёт колонкам место под содержимое. В этом уроке — MergeCell и UnmergeCell, ловушки чтения файлов со слияниями, SetColWidth с честным разбором единиц, высота строк и приём автоширины по содержимому, которого в библиотеке из коробки нет.

Содержание урока · 9 разделов

У стилей из прошлых уроков есть слепая зона: они красят ячейки, но не двигают их. А почти каждый настоящий отчёт требует геометрии: шапка «Итоги за II квартал» растягивается над тремя колонками, длинное наименование не помещается в ячейку шириной восемь символов, строка заголовка сжимает крупный шрифт в узкую полоску. Это три отдельные ручки листа — объединение ячеек, ширина столбцов и высота строк. В отличие от стилей, они применяются не через идентификаторы, а прямыми вызовами на файле: MergeCell, SetColWidth и SetRowHeight. Объединения работают в обе стороны: шапку тянут по горизонтали над колонками, а вертикальные блоки — в декоративных зонах вроде боковика с названием раздела, хотя слияния внутри колонок данных, как увидим ниже, удовольствие сомнительное. Порядок работы свободный, но в отчётах ручки обычно проходят сверху вниз: сначала собирают шапку с объединениями, потом расставляют ширины под данные, в конце подгоняют высоты. И стили из прошлых уроков пригодятся сразу: объединённый блок красится тем же SetCellStyle, только диапазон теперь совпадает с областью слияния — на этом правиле здесь будет отдельная врезка.

MergeCell: excelize mergecell собирает один блок#

Метод f.MergeCell принимает лист и две ячейки: верхнюю-левую и нижнюю-правую будущего блока — и помечает прямоугольник как один. Вызов f.MergeCell("Отчёт", "A1", "D1") растягивает первую строку на четыре колонки, а тот же метод с координатами A10 и A20 соберёт вертикальный блок из одиннадцати строк — так оформляют боковики и зоны-разделители. Значение живёт в верхней-левой ячейке: Excel рисует его по всей площади блока, а физически остальные ячейки пусты — пишите значение до слияния или после, лишь бы по координате угла. Повторное слияние того же диапазона excelize отклонит ошибкой, как и пересечение с уже объединённым блоком: карта слияний хранится в файле, и библиотека проверяет её перед записью. Снимается слияние зеркально: UnmergeCell с теми же координатами — значение остаётся в углу, остальные ячейки снова становятся обычными. Важно понимать границы операции: слияние не склеивает тексты и не суммирует числа, это про геометрию, а не про данные. Для аудита есть GetMergeCells: вернёт список блоков листа с начальной и конечной координатами, и чужой файл разумно просматривать именно с этой карты.

Шапка на четыре колонки

GO
f.SetCellValue("Отчёт", "A1", "Отчёт за второй квартал")

if err := f.MergeCell("Отчёт", "A1", "D1"); err != nil {
    panic(err)
}

header, err := f.NewStyle(&excelize.Style{
    Font: &excelize.Font{Bold: true, Size: 13},
    Alignment: &excelize.Alignment{
        Horizontal: "center",
        Vertical:   "center",
    },
})
if err != nil {
    panic(err)
}

if err := f.SetCellStyle("Отчёт", "A1", "D1", header); err != nil {
    panic(err)
}

Значение пишется в верхнюю-левую ячейку, слияние накрывает прямоугольник, стиль прикладывается тем же прямоугольником: выравнивание центрует содержимое блока, а заливка и рамки из прошлых уроков лягут на каждую ячейку. Примените стиль только к A1 — и покрашется один угол шапки.

Чтение файла со слияниями#

Плата за красивую шапку приходит при чтении собственного файла. GetRows вернёт текст в первой ячейке блока и пустые строки в остальных: построчный парсер увидит строку, где три ячейки пусты, и решит, что данные кончились. GetCellValue("C1") вернёт пустую строку, хотя на экране Excel показывает заголовок по всей площади блока. Отсюда правило разделения труда: слияния — для декоративных зон, заголовков, подписей и периодов; данные живут по одной ячейке на значение. Шапку объединить можно и нужно, колонку с ценами — не стоит: импорт из урока про чтение ячеек сломается на ровном месте, а поиск причины затянется на вечер. Вертикальные слияния в данных мешают сильнее горизонтальных: колонка категорий, слитая на десять строк, в GetRows выглядит как одна заполненная и девять пустых, и группировка по ней соберёт мусор. Если файлы со слияниями приходят со стороны, первым делом постройте карту блоков через GetMergeCells — парсеру она нужнее самих строк, потому что отличает честные пустые ячейки от пустых внутри объединения.

SetColWidth: ширина столбцов excelize в символах#

Метод f.SetColWidth принимает лист, начальную и конечную колонку и ширину — один вызов покрывает диапазон: SetColWidth("Отчёт", "B", "D", 14) задаст ширину трём колонкам сразу, для одной начало и конец совпадают. Единица — не пиксель: ширина столбцов excelize измеряет в символах шрифта по умолчанию, точнее в ширине цифры ноль базового шрифта, поэтому 14 на Calibri и на другом шрифте занимают разное место. Предел — 255 символов, а колонка без явной ширины узкая, около 8.43. Значение пишется в файл и рисуется как есть: библиотека не измеряет содержимое, а в xlsx нет понятия «ширина текста» до открытия файла в Excel. Отсюда и отсутствие автоподбора из коробки: команда «автоширина» живёт в Excel и пересчитывает ширину по факту отображения. В генераторах автоподбор эмулируют: посчитать максимум длины строки в колонке и выставить SetColWidth с запасом — приём в коде ниже.

Автоширина по содержимому

GO
rows, err := f.GetRows("Отчёт")
if err != nil {
    panic(err)
}

const cols = 4
for i := 0; i < cols; i++ {
    widest := 8.0
    for _, row := range rows {
        if i < len(row) {
            if l := float64(len([]rune(row[i]))); l > widest {
                widest = l
            }
        }
    }
    col, _ := excelize.ColumnNumberToName(i + 1)
    f.SetColWidth("Отчёт", col, col, widest*1.1+2)
}

Максимум длины строки в колонке считается в рунах: русские буквы занимают два байта в UTF-8, и подсчёт по байтам раздул бы колонку вдвое. Константа 8.0 держит нижнюю границу на уровне дефолта, множитель 1.1 и плюс два символа дают запас под шрифт. Считайте по отображаемым значениям: серийный номер даты короче строки 15.06.2024, которая видна на экране.

Методы размеров одним взглядом#

ВызовЧто делаетЕдиницы
f.MergeCell("Отчёт", "A1", "D1")объединяет прямоугольник в один блокячейки
f.UnmergeCell("Отчёт", "A1", "D1")снимает слияние по тем же координатамячейки
f.SetColWidth("Отчёт", "B", "D", 14)ширина колонок диапазономсимволы шрифта
f.GetColWidth("Отчёт", "B")текущая ширина колонкисимволы шрифта
f.SetRowHeight("Отчёт", 1, 26)высота строкипункты
f.GetRowHeight("Отчёт", 2)текущая высота строкипункты

Высота строк и решётки вместо чисел#

Высота задаётся SetRowHeight в пунктах: по умолчанию строка около 15 пунктов, шапке с тринадцатым шрифтом ставят 22–26, иначе верхушки букв упираются в границу. С переносом текста из урока про стили есть нюанс: Excel растит строку под переносимый текст сам, но только пока высота не задана вручную — после SetRowHeight автоподбор для этой строки отключается, и длинный текст обрезается. Числа ведут себя иначе текста: когда колонке не хватает ширины, Excel не обрезает значение и не лезет на соседей, а рисует решётки ##### — страдают деньги и даты первыми, у текста есть выход на пустую соседку. Датам формата DD.MM.YYYY из урока про форматы чисел и дат нужно десять символов, а колонка по умолчанию — около 8.43: вот и решётки на первой же выгрузке. Лечение одно: ширину считает генератор по отображаемым значениям, а не надежда, что кто-то потянет границу колонки в Excel.

Чек-лист размеров#

  • MergeCell — прямоугольник в один блок: значение живёт в верхней-левой ячейке.
  • Стиль блока прикладывайте на весь диапазон слияния, а не на угол.
  • GetRows под слиянием видит пустые ячейки: данные держите без объединений.
  • SetColWidth — ширина в символах шрифта: от и до, предел 255.
  • SetRowHeight — высота в пунктах: шапке 22–26, данным по умолчанию.
  • Решётки ##### — числу не хватило ширины: ширину считает генератор.

Кейс про решётки на фото экрана. Руководителю прислали квартальный отчёт, он открыл его и отправил назад скриншот: колонка дат вся в решётках, колонка денег — тоже. Причина считалась на пальцах: даты писались time.Time со стилем DD.MM.YYYY, отображаемая строка 15.06.2024 — десять символов, ширина колонки — дефолтные 8.43. Ширину посчитал генератор: максимум по отображаемым значениям каждой колонки, множитель 1.1 и два символа запаса; деньгам с рублём досталось 14, датам 12. Заголовок заодно объединили в один блок и подняли шапке высоту до 26. В команду ушло правило: файл открывается готовым, границу колонки в Excel никто не тянет. Ширины вынесли в константы рядом с описанием колонок отчёта: данные и их размеры живут в одном месте, и новая колонка добавляется одним блоком, а не правкой в двух концах файла. Спорная сторона: автоширина по максимуму раздувает колонку из-за одного выброса на двести строк; там, где выбросы ожидаемы, максимум отбрасывают и включают перенос текста — решение по данным, а не по вкусу.

Проверка: где живёт значение блока

После f.MergeCell("Отчёт", "A1", "D1") где окажется значение ячейки A1?

Проверка: ширина диапазоном

Какой вызов задаст ширину колонок B, C и D одной строкой?

Что вернёт чтение из блока?

Прочитайте код и выберите, что он выведет:

f.SetCellValue("Sheet1", "A1", "Отчёт за квартал")

f.MergeCell("Sheet1", "A1", "D1")

val, _ := f.GetCellValue("Sheet1", "C1")

fmt.Println(val)

Соберите шапку по размеру

Допишите объединение блока, перевод номера колонки в букву, ширину и высоту.

f.("Отчёт", "A1", "D1") col, _ := excelize.(2) f.("Отчёт", col, col, 18) f.("Отчёт", 1, 26)

Соберите шапку и её размеры

Расставьте строки в порядке выполнения: написать заголовок, объединить блок, создать стиль, проверить ошибку, применить стиль к блоку, задать ширину колонок.

Строки

Ваша программа

Нажимайте на строки слева, чтобы собрать программу

Карточки: слияния и размеры

Термин

MergeCell

нажмите, чтобы перевернуть
Определение

Объединяет прямоугольник ячеек в блок: лист, верхняя-левая, нижняя-правая. Значение живёт в углу, остальные ячейки пусты.

1 / 6

Геометрия закрыта: шапка стоит блоком, колонки не жмут данные, высота строк подогнана. Дальше файл станет умнее: в уроке про формулы итоги посчитает сам Excel через SetCellFormula, а в уроке про условное форматирование колонка подсветит отрицательные остатки без единого нового стиля. Стили, границы и размеры из последних четырёх уроков складываются в готовый шаблон оформления — целиком он используется в экспорте отчёта из базы и в разборе типичных ошибок excelize. Если длина строки в рунах показалась тёмной темой, вернитесь к уроку про строки и руны базового курса. Домашнее задание — шапка блоком и ширина по содержимому.

Песочница урока

Редактируйте код и запускайте его прямо здесь — интерпретатор работает в браузере, ничего устанавливать не нужно. За каждый запуск — +2 XP.

Вывод

Запустите код, чтобы увидеть вывод.

Коротко: что запомнить

  • MergeCell объединяет прямоугольник ячеек: значение остаётся в верхней-левой.
  • Стиль слияния прикладывайте ко всему блоку, а не к углу.
  • Чтение возвращает пустые строки для ячеек под слиянием: парсер должен знать карту блоков.
  • SetColWidth задаёт ширину в символах шрифта: от и до, предел 255.
  • SetRowHeight измеряет высоту в пунктах; ручная высота отключает автоподбор при переносе.
  • Решётки ##### — числу не хватило ширины: ширину считает генератор по отображаемым значениям.

Домашнее задание

В своём отчёте объедините шапку листа в один блок на все колонки данных и отцентрируйте её, поднимите высоту строки до 26, а колонкам посчитайте ширину по максимуму отображаемой длины с множителем 1.1 и двумя символами запаса. Проверьте GetMergeCells, что блок один, и убедитесь, что ни одна числовая колонка не показывает решётки.

Личные заметкиПусто
Хранятся только в вашем браузере (Excelize · Слияние и ширина: MergeCell и SetColWidth)

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

Что вернёт GetCellValue для ячейки внутри слияния?

Пустую строку: значение хранится в верхней-левой ячейке блока, остальные Excel держит пустыми. На экране текст виден по всей площади, но чтение по отдельным ячейкам его не отдаёт — читайте угловую координату.

Почему после MergeCell шапка покрашена наполовину?

Стиль применили только к угловой ячейке: заливка и границы лежат на каждой ячейке блока отдельно. Прикладывайте стиль SetCellStyle на тот же прямоугольник, что и слияние, — тогда оформление накроет весь блок.

Есть ли в excelize автоподбор ширины, как в Excel?

Из коробки нет: в файле не хранится ширина содержимого, и библиотеке нечего измерять до открытия файла. Ширину считают при генерации — максимум длины отображаемых значений колонки, множитель 1.1 и пара символов запаса через SetColWidth.

Термины урока

Ключевые понятия из этого урока — короткие определения в глоссарии. Наведите на термин, чтобы вспомнить, откройте карточку для подробностей и ссылки на практику.

Следующая ступень учебного пути

Cron25 уроков~9 чпрактика25 уроков уже доступны

Фоновые задачи в Go: планировщик на robfig/cron

Курс по cron в Go: robfig/cron v3, синтаксис выражений, пояса, wrappers, конкурентность и graceful shutdown. 25 уроков с примерами и проектом.

  • Собирать планировщик на robfig/cron v3 и запускать задачи по расписанию
  • Читать и писать cron-выражения: пять полей, спецсимволы, @daily
  • Управлять жизненным циклом: Start, Stop, Entry, Remove
  • Держать часовые пояса и секундные расписания под контролем