shad-go/excelwriter/README.md

67 lines
4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# excelwriter [reflect]
В этой задаче нужно обернуть библиотеку для работы с exel'ем в reflect, реализовав интерфейс для построчной записи go объектов в excel
```go
type Writer interface {
WriteRow(r any) error
}
```
r — это либо структура, либо map[smth]any, либо указатель на что-то из этого.
smth — это либо строка, либо тип реализующий [TextMarshaler](https://pkg.go.dev/encoding#TextMarshaler)
Как должны сериализовываться поля структур подробно написано в интерфейсе.
Всё, что не специфицировано в доке и не проверяется тестами можно делать как сочтёте разумным.
Также нужно реализовать конструктор
```go
func New(f *excelize.File) Writer {
panic("implement me")
}
```
принимающий на вход инициализированный excel клиент.
Можно считать, что excel файл изначально пустой у которого создана 1 страница. Все записи нужно делать в ней.
Пример использования
```go
type Movie struct {
Title string
Year int `xlsx:"release_year"`
}
func StoreMovies() {
f := excelize.NewFile()
_, _ = f.NewSheet("Sheet1")
w := excelwriter.New(f)
_ = w.WriteRow(&Movie{Title: "Blade Runner", Year: 1982})
_ = w.WriteRow(&Movie{Title: "Blade Runner 2049", Year: 2017})
_ = w.WriteRow(map[string]any{"title": "Into the wild", "release_year": 2007})
out, _ := os.Create("/tmp/movie.xlsx")
_, _ = f.WriteTo(out)
}
```
В результате будет создан excel документ со следующим содержимым
```
title release_year
Blade Runner 1982
Blade Runner 2049 2017
Into the wild 2007
```
В первой строке хранятся имена колонок, которые вычисляются из имён полей, тэгов и ключей map'ов.
Разные структуры могут превращаться в разные наборы колонок.
Для каждого уникального имени должна быть ровно одна колонка, их нужно "создавать" по мере возникновения.
Новые ключи каждого конкретного мапа добавляются в колонки в отсортированном порядке, чтобы при перезапусках на одних и тех же данных получались одинаковые excel'ки.
Помимо имён полей в xlsx тэгах для числовых полей нужно поддержать стили форматирования.
Например, в excel нет отдельного типа для дат. Дата — это 15-и значный double (excel тип Number) со стилем форматирования `d-mmm-yy`. Библиотека для работы с excel'ем определяет [наборы популярных стилей](https://pkg.go.dev/github.com/xuri/excelize/v2#File.NewStyle) в виде enum'а `15 d-mmm-yy`. Это число 15 и нужно поддержать в тэге `xslx:"date,numfmt:15"`.
## Вопросы со звёздочкой
1. Как бы вы поддержали в тэгах стили форматирования ячеек (excelize.Fill, excelize.Border ...)?
2. Как бы вы поддержали в тэгах кастомные стили форматирования числовых значений, те, что не входят в стандартный набор, например `0,"K"`?
3. Как мог бы выглядеть Reader, совместимый с Writer'ом, читающий строчки из excel в Go структуры и map'ы?