- Исправлена двойная обработка ITableRow через reflection - Исправлен выход за границы изображения при отрисовке последнего разделителя - Добавлена защита от пустых данных (header, blocks) - Добавлена compile-time проверка интерфейса ITableRow - Переименован tablle_block_style.go → table_block_style.go - Добавлены комментарии на русском ко всем функциям и типам - Написана документация README.md с примерами использования - Добавлен CLAUDE.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.0 KiB
image_table
Go-библиотека для рендеринга таблиц данных в PNG-изображения. Подходит для генерации отчётов, уведомлений в мессенджерах и визуализации табличных данных.
Установка
go get git.gm6.ru/icewind/image_table
Возможности
- Рендеринг одиночной таблицы с автоподбором ширины столбцов
- Рендеринг документа из нескольких именованных таблиц
- Поддержка различных типов данных в строках: срезы, структуры, интерфейс
ITableRow - Настройка цвета фона для отдельных строк через
TableBlockStyle - Встроенный шрифт JetBrains Mono — не требует внешних зависимостей для шрифтов
Примеры
Простая таблица
package main
import (
"image/png"
"os"
"git.gm6.ru/icewind/image_table"
)
func main() {
header := []string{"Имя", "Возраст", "Город"}
rows := []any{
[]string{"Алиса", "23", "Москва"},
[]string{"Боб", "31", "Казань"},
[]string{"Олег", "44", "Сочи"},
}
img := image_table.DrawTableWarm(header, rows)
file, _ := os.Create("table.png")
defer file.Close()
png.Encode(file, img)
}
Строки из структур
Поля структуры автоматически преобразуются в ячейки таблицы:
type User struct {
Name string
Age int
City string
}
rows := []any{
User{"Елена", 27, "Минск"},
User{"Иван", 35, "Киев"},
}
img := image_table.DrawTableWarm(
[]string{"Имя", "Возраст", "Город"},
rows,
)
Строки с пользовательским фоном
Используйте TableBlockStyle для задания цвета фона строки:
rows := []any{
[]any{1, "Запрос обработан", "OK"},
&image_table.TableBlockStyle{
Cells: []any{2, "Ошибка соединения", "FAIL"},
BackgroundColor: color.RGBA{R: 255, G: 225, B: 225, A: 255}, // красный фон
},
}
img := image_table.DrawTableWarm(
[]string{"ID", "Описание", "Статус"},
rows,
)
Важно:
TableBlockStyleнужно передавать как указатель (&TableBlockStyle{...}), иначе интерфейсITableRowне будет распознан.
Документ из нескольких таблиц
Document позволяет объединить несколько таблиц с заголовками в одно изображение:
doc := image_table.Document{
Blocks: []image_table.TableBlock{
{
Title: "Пользователи",
Header: []string{"ID", "Имя", "Возраст"},
Rows: []any{
[]any{1, "Иван", 30},
[]any{2, "Мария", 25},
},
},
{
Title: "Статистика",
Header: []string{"Метрика", "Значение"},
Rows: []any{
[]any{"Запросы", 12000},
&image_table.TableBlockStyle{
Cells: []any{"Ошибки", 37},
BackgroundColor: color.RGBA{R: 255, G: 225, B: 225, A: 255},
},
},
},
},
}
img := image_table.RenderDocument(doc)
file, _ := os.Create("document.png")
defer file.Close()
png.Encode(file, img)
Собственная реализация ITableRow
Для полного контроля над строкой реализуйте интерфейс ITableRow:
type AlertRow struct {
Level string
Message string
}
func (r *AlertRow) GetCells() []any {
return []any{r.Level, r.Message}
}
func (r *AlertRow) GetBackgroundColor() color.RGBA {
if r.Level == "CRITICAL" {
return color.RGBA{R: 255, G: 200, B: 200, A: 255}
}
return color.RGBA{R: 255, G: 255, B: 255, A: 255}
}
API
DrawTableWarm(header []string, rows []any) image.Image
Рендерит одну таблицу. Строки могут быть []string, []any, структурой или реализацией ITableRow.
RenderDocument(doc Document) image.Image
Рендерит документ из нескольких таблиц (Document.Blocks), каждая с заголовком.
ITableRow
type ITableRow interface {
GetCells() []any
GetBackgroundColor() color.RGBA
}
Интерфейс для строк с пользовательским стилем. Готовая реализация — TableBlockStyle.
Лицензия
MIT