https://github.com/bookfx/bookfx
Composing Excel spreadsheets based on a tree of nested components like the HTML DOM.
https://github.com/bookfx/bookfx
excel netstandard ooxml openxml xlsx
Last synced: about 1 month ago
JSON representation
Composing Excel spreadsheets based on a tree of nested components like the HTML DOM.
- Host: GitHub
- URL: https://github.com/bookfx/bookfx
- Owner: bookfx
- License: lgpl-3.0
- Created: 2019-10-29T14:30:35.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-02-11T08:24:57.000Z (about 4 years ago)
- Last Synced: 2025-10-31T20:02:08.134Z (4 months ago)
- Topics: excel, netstandard, ooxml, openxml, xlsx
- Language: C#
- Homepage:
- Size: 574 KB
- Stars: 109
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README-ru.md
- License: COPYING
Awesome Lists containing this project
README
# BookFx
[![nuget-img][]][nuget-link]
[![build-img][]][build-link]
[![tests-img][]][tests-link]
[![quality-img][]][quality-link]
[en][] | **ru**
BookFx предоставляет экстремально эффективный способ создания книг Excel любой сложности.
```c#
Make.Book().ToBytes()
```
И у нас уже есть xlsx с одним пустым листом!
![book-empty][]
Более приветливый вариант:
```c#
Make.Value("Hi, World!").ToSheet().ToBook().ToBytes()
```
![box-a1][]
Композиция вместо высчитывания адресов,
компонентный подход для устранения сложности,
функциональный стиль вместо VBA-подобной императивщины,
прототипирование компонентов со слотами из частей заготовленных xlsx-файлов,
формулы, шрифты, цвета, выравнивания, форматы.
Обо всем этом ниже.
BookFx требует [.NET Standard 2.0][.net standard 2.0] и зависит от [EPPlus][epplus], который используется в качестве рендера в формат XLSX Office Open XML.
## Содержание
- [Установка](#установка)
- [Начало работы](#начало-работы)
- [Примеры использования](#примеры-использования)
- [Концепции](#концепции)
- [Описание модели](#описание-модели)
- [Система размещения](#система-размещения)
- [Охват и объединение](#охват-и-объединение)
- [Значения и формулы](#значения-и-формулы)
- [Прототипирование](#прототипирование)
- [Справочник API](#справочник-api)
- [Лицензия](#лицензия)
## Установка
```shell
PM> Install-Package BookFx
```
## Начало работы
### Создание
Точка входа BookFx это класс `Make`.
Он предоставляет методы для создания книг, листов, box'ов, стилей и границ.
Точка выхода это `ToBytes()`.
Основные свойства классов BookFx могут быть заданы с использованием перегрузок методов `Make`:
```c#
Make.Book(Make.Sheet("First"), Make.Sheet("Second")).ToBytes()
```
Другой способ это chaining:
```c#
Make
.Book()
.Add(Make.Sheet().Name("First"))
.Add(Make.Sheet().Name("Second"))
.ToBytes()
```
Результат обоих примеров один и тот же.
![sheet-name][]
### Боксы
`Box` это строительный блок листа.
Он может быть составным и всегда описывает диапазон — ячейку, строку, колонку или прямоугольник из ячеек.
В таблице перечислены все типы box'ов.
| Тип | Создание | Назначение |
| -- | -- | -- |
| `ValueBox` | `Make.Value()` | Значения, формулы и пустые диапазоны. |
| `RowBox` | `Make.Row()` | Размещение box'ов слева направо. |
| `ColBox` | `Make.Col()` | Размещение box'ов сверху вниз. |
| `StackBox` | `Make.Stack()` | Размещение box'ов слоями. |
| `ProtoBox` | `Make.Proto()` | Составление из шаблонов. |
Что если поместить в `RowBox` два `ValueBox`'а?
```c#
Make.Row(Make.Value("Box A1"), Make.Value("Box B1")).ToSheet().ToBook().ToBytes()
```
![box-a1-b1][]
Логично. Два значения расположились в строку!
### Преобразования
В `ValueBox` реализованы [неявные преобразования][implicit convertions] из всех необходимых типов значений.
Что это значит?
Это значит, что не обязательно каждый раз повторять `Make.Value`,
потому что `ValueBox` будет создан автоматически.
```c#
Make.Row("Box A1", "Box B1").ToSheet().ToBook().ToBytes()
```
![box-a1-b1][]
Результат тот же самый!
### Композиция
Опишем вот такую шапку таблицы:
![box-header][]
В терминах BookFx она может быть представлена как композиция элементов, вот так:
![box-header-model][]
Легко увидеть общий паттерн.
![box-plan-fact-model][]
Мы можем извлечь этот паттерн в функцию:
```c#
Box PlanFact(string title) => Make.Col(title, Make.Row("Plan", "Fact"));
```
По сути это простой компонент. Протестируем его:
```c#
PlanFact("Beginning of year").ToSheet().ToBook().ToBytes()
```
![box-plan-fact][]
Теперь используем `PlanFact` как компонент и добавим стиль:
```c#
Box Head() => Make
.Row()
.Add("Code", "Name", PlanFact("Beginning of year"), PlanFact("End of year"))
.Style(Make.Style().Center().Middle().Bold().DefaultBorder());
```
О, так это же еще один компонент!
Что же это получается?
Компонент – это функция. Функция – это компонент...
Похоже в наших руках безграничные возможности!
Теперь все просто:
```c#
Head().AutoSpan().ToSheet().ToBook().ToBytes()
```
![box-header][]
Готово.
Про `AutoSpan` можно почитать в разделе [Охват и объединение](#охват-и-объединение).
Полная версия в примерах использования ниже.
## Примеры использования
Проект `BookFx.Usage` содержит несколько примеров использования. Результаты его выполнения сохраняются в папку `src\BookFx.Usage\bin\Debug\netcoreapp2.1\Results\`.
### [S1Table.cs][s1table.cs]
Это полная версия примера из [Начало работы](#начало-работы). Она создает таблицу с итогами.
### [S2Style.cs][s2style.cs]
Этот пример демонстрирует некоторые возможности стилей BookFx.
### [S3Calendar.cs][s3calendar.cs]
Ого! Календарь!
[![s-3-calendar][]][s3calendar.cs]
### [S5ProtoSheet.cs][s5protosheet.cs]
Это демонстрация добавления в книгу листов из существующих книг. См. также [Прототипирование](#прототипирование).
### [S6ProtoBox.cs][s6protobox.cs]
Это пример [прототипирования](#прототипирование).
### [S7BalanceSheet.cs][s7balancesheet.cs]
Это демонстрация создания балансового отчета с шапкой и переменным количеством колонок и строк данных.
## Концепции
### Описание модели
Модель книги BookFx чем-то похожа на HTML [DOM][dom].
Это дерево узлов, которое рендерится в xlsx-файл.
Такой подход открывает множество возможностей:
- узлы могут быть реализованы как повторно используемые компоненты;
- размещение узлов определяется их композицией;
- к иерархии узлов удобно применять стили;
- для unit-тестирования не требуется рендеринг книги.
Модель BookFx неизменяемая ([immutable][immutable object]),
и у методов библиотеки нет побочных эффектов ([side effects][side effect]),
поэтому BookFx позволяет писать чистые функции ([pure functions][pure function]).
Таким образом, BookFx:
- помогает лучше структурировать описание книги;
- берет на себя вычисления размеров и адресов диапазонов;
- избавляет от необходимости использовать императивный API, пришедший из мира VBA-макросов;
- раскрывает возможности функционального программирования.
### Система размещения
Каждый лист книги может содержать один корневой box. Он размещается в верхнем левом углу.
Составные box'ы содержат внутри себя другие box'ы и растягиваются чтобы вместить их:
- внутри `RowBox` box'ы располагаются в строку слева направо;
- внутри `ColBox` box'ы располагаются в колонку сверху вниз;
- внутри `StackBox` box'ы располагаются в стопку один над другим.
`ValueBox` не может содержать другие box'ы, но может располагаться на нескольких ячейках.
Подробнее об этом в разделе [Охват и объединение](#охват-и-объединение).
Размер `ProtoBox` всегда равен размеру прототипа, а внутренние box'ы `ProtoBox`'а размещаются с использованием механизма слотов. Подробнее в разделе [Прототипирование](#прототипирование).
### Охват и объединение
`ValueBox`, как и любой другой тип box'а, может располагаться на нескольких ячейках.
Для определения количества охватываемых `ValueBox` ячеек используются методы `SpanRows`, `SpanCols` и их комбинация `Span`.
Охват ячеек внутри `ValueBox` похож на работу атрибутов `rowspan` и `colspan` HTML-таблиц, однако в BookFx ячейки внутри `ValueBox` не всегда должны быть объединены.
Для объединения ячеек используется метод `Merge`, но BookFx объединяет диапазоны `ValueBox` автоматически, если в box'е есть значение или формула. В некоторых случаях может потребоваться не объединять ячейки автоматически. Для этого используется `Merge(false)`.
Кроме автоматического объединения BookFx поддерживает автоматический охват, который включается методами `AutoSpanRows`, `AutoSpanCols` и их комбинацией `AutoSpan`. В этом режиме box и все включенные в него box'ы растягиваются до размеров своих контейнеров за счет последних растягиваемых `ValueBox`'ов. `ValueBox` считается растягиваемым, если для него не задан `Span` и для него не выключен `AutoSpan`. Мы уже использовали `AutoSpan` в разделе [Начало работы](#начало-работы).
### Значения и формулы
И для значений, и для формул предназначен `ValueBox`,
который может быть создан либо с помощью `Make.Value`, либо с помощью неявного преобразования из всех необходимых типов значений: `string`, `int`, `decimal`, `DateTime` и др.
Формулы должны начинаться с `=`. Для экранирования используется символ `'`. Поддерживается только стиль ссылок `R1C1`.
```c#
Make.Value("=SUM(RC[1]:RC[3])")
```
### Прототипирование
BookFx поддерживает использование фрагментов других книг в качестве прототипов:
```c#
Make
.Proto(protoBook, "Prototype1")
.Add("Slot1", "Value1")
.Add("Slot2", Make.Row("Value2", "Value3"));
```
Здесь
- `protoBook` – `byte[]` содержимого xlsx-файла;
- `"Prototype1"` – имя диапазона в `protoBook`;
- `"Slot1"` и `"Slot2"` – имена диапазонов внутри `Prototype1`, в которых могут размещаться другие box'ы.
См. пример [S6ProtoBox.cs][s6protobox.cs].
Также BookFx поддерживает добавление целых листов из других книг:
```c#
Make.Sheet("New Sheet Name", protoBook, "Prototype Sheet Name");
```
Из xlsx-файла `protoBook` будет скопирован лист `"Prototype Sheet Name"` и переименован в `"New Sheet Name"`. См. также другие перегрузки `Make.Sheet`.
См. также пример [S5ProtoSheet.cs][s5protosheet.cs].
## Справочник API
- `Make` - фабрика элементов модели
- `Make.Book` - создать `Book`
- `Make.Sheet` - создать `Sheet`
- `Make.Row` - создать `RowBox`
- `Make.Col` - создать `ColBox`
- `Make.Stack` - создать `StackBox`
- `Make.Value` - создать `ValueBox`
- `Make.Proto` - создать `ProtoBox`
- `Make.Style` - создать `BoxStyle`
- `Make.Border` - создать `BoxBorder`
- `Book` - книга Excel
- `Book.Add` - добавить лист(ы)
- `Book.ToBytes` - выполнить рендеринг в xlsx
- `Sheet` - лист Excel
- `Sheet.Name` - задать имя листа
- `Sheet.TabColor` - задать цвет вкладки
- `Sheet.SetPageView` - задать режим отображения
- `Sheet.Portrait` - задать книжную ориентацию страницы
- `Sheet.Landscape` - задать альбомную ориентацию страницы
- `Sheet.Margin` - задать поля страницы
- `Sheet.Fit` - вписать содержимое по высоте и ширине
- `Sheet.FitToHeight` - вписать содержимое по высоте
- `Sheet.FitToWidth` - вписать содержимое по ширине
- `Sheet.Scale` - задать масштаб
- `Sheet.ToBook` - создать `Book` с одним листом
- `Box` - box любого вида
- `Box.NameGlobally` - присвоить диапазону имя области книги
- `Box.NameLocally` - присвоить диапазону имя области листа
- `Box.AutoSpan` - включить режим `AutoSpan` для строк и колонок
- `Box.AutoSpanRows` - включить режим `AutoSpan` для строк
- `Box.AutoSpanCols` - включить режим `AutoSpan` для колонок
- `Box.Style` - задать стиль
- `Box.SizeRows` - задать высоту строк
- `Box.SizeCols` - задать ширину колонок
- `Box.SetPrintArea` - задать область печати по box'у
- `Box.HideRows` - скрыть строки
- `Box.HideCols` - скрыть колонки
- `Box.Freeze` - закрепить область box'а
- `Box.FreezeRows` - закрепить строки box'а
- `Box.FreezeCols` - закрепить колонки box'а
- `Box.AutoFilter` - добавить автофильтр в нижней строке box'а
- `Box.ToSheet` - создать `Sheet` с корневым box'ом
- `RowBox` - строка box'ов
- `RowBox.Add` - добавить box(ы) в строку
- `ColBox` - колонка box'ов
- `ColBox.Add` - добавить box(ы) в колонку
- `StackBox` - стопка box'ов
- `StackBox.Add` - добавить box(ы) в стопку
- `ValueBox` - box со значением, формулой, или пустой box
- `ValueBox.Span` - охватить строки и колонки
- `ValueBox.SpanRows` - охватить строки
- `ValueBox.SpanCols` - охватить колонки
- `ValueBox.Merge` - объединить ячейки
- `ProtoBox` - прототип
- `ProtoBox.Add` - добавить box в слот
- `BoxStyle` - стиль
- `BoxStyle.Borders` - задать границы
- `BoxStyle.DefaultBorder` - задать обычные границы
- `BoxStyle.Font` - задать шрифт, его размер и цвет
- `BoxStyle.Back` - задать цвет фона
- `BoxStyle.Color` - задать цвет шрифта и/или цвет фона
- `BoxStyle.Bold` - выделить жирным
- `BoxStyle.Italic` - выделить курсивом
- `BoxStyle.Underline` - подчеркнуть
- `BoxStyle.Strike` - зачеркнуть
- `BoxStyle.Wrap` - задать перенос текста
- `BoxStyle.Shrink` - задать автоподбор ширины текста
- `BoxStyle.Align` - задать выравнивание
- `BoxStyle.Left` - выровнять по левому краю
- `BoxStyle.Center` - выровнять горизонтально по центру
- `BoxStyle.CenterContinuous` - выровнять горизонтально по центру смежных ячеек
- `BoxStyle.Right` - выровнять по правому краю
- `BoxStyle.Top` - выровнять по верхнему краю
- `BoxStyle.Middle` - выровнять вертикально по середине
- `BoxStyle.Bottom` - выровнять по нижнему краю
- `BoxStyle.RotateCounterclockwise` - повернуть текст против часовой стрелки
- `BoxStyle.RotateClockwise` - повернуть текст по часовой стрелке
- `BoxStyle.Indent` - задать отступ
- `BoxStyle.Format` - задать произвольный формат
- `BoxStyle.DefaultFormat` - задать формат `General` (Общий)
- `BoxStyle.Text` - задать формат `@` (Текстовый)
- `BoxStyle.Integer` - задать формат `#,##0` (Целое число)
- `BoxStyle.Money` - задать формат `#,##0.00` (Числовой с разделителем триад)
- `BoxStyle.Percent` - задать формат `0%` (Процентный, целое)
- `BoxStyle.DateShort` - задать формат `dd.mm.yyyy` (Краткий формат даты)
- `BoxBorder` - граница
- `BoxBorder.Restrict` - ограничить часть box'а, к которой применяется граница
- `BoxBorder.Style` - задать стиль границы
- `BoxBorder.Color` - задать цвет границы
- `EnumerableExt` - расширения IEnumerable для типов BookFx
- `IEnumerable.ToBook` - создать `Book` из листов
- `IEnumerable.ToRow` - создать `RowBox` из других box'ов
- `IEnumerable.ToCol` - создать `ColBox` из других box'ов
- `IEnumerable.ToStack` - создать `StackBox` из других box'ов
- `IEnumerable.Mix` - смешать стили и создать новый
## Лицензия
Этот проект лицензируется под [LGPL-3.0-or-later](https://spdx.org/licenses/LGPL-3.0-or-later.html).
### Уведомление об авторском праве
``` txt
BookFx. Composing Excel spreadsheets based on a tree of nested components like the HTML DOM.
Copyright (c) 2019–2022 Zhenya Gusev
```
### Уведомление о лицензии
``` txt
Эта библиотека является свободным программным обеспечением:
Вы можете распространять и/или изменять ее,
соблюдая условия Меньшей генеральной публичной лицензии GNU,
опубликованной Фондом свободного программного обеспечения;
либо редакции 3 Лицензии, либо любой редакции, выпущенной позже.
Эта библиотека распространяется в расчете на то, что она окажется полезной,
но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая подразумеваемую гарантию КАЧЕСТВА либо
ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Меньшей генеральной
публичной лицензией GNU для получения более подробной информации.
Вы должны были получить копию Меньшей генеральной публичной лицензии GNU
вместе с этой библиотекой. Если Вы ее не получили, то перейдите по адресу:
.
```
[nuget-img]: https://img.shields.io/nuget/v/BookFx?color=informational
[nuget-link]: https://www.nuget.org/packages/BookFx
[build-img]: https://img.shields.io/appveyor/ci/bookfx/bookfx/master
[build-link]: https://ci.appveyor.com/project/bookfx/bookfx
[tests-img]: https://img.shields.io/appveyor/tests/bookfx/bookfx/master
[tests-link]: https://ci.appveyor.com/project/bookfx/bookfx
[quality-img]: https://img.shields.io/codacy/grade/bccabc29ebf943ba89ac4a1d03b5e70a/master
[quality-link]: https://app.codacy.com/gh/bookfx/bookfx/dashboard
[en]: README.md
[dom]: https://en.wikipedia.org/wiki/Document_Object_Model
[immutable object]: https://en.wikipedia.org/wiki/Immutable_object
[side effect]: https://en.wikipedia.org/wiki/Side_effect_(computer_science)
[pure function]: https://en.wikipedia.org/wiki/Functional_programming#Pure_functions
[.net standard 2.0]: https://github.com/dotnet/standard/blob/v2.1.0/docs/versions/netstandard2.0.md
[epplus]: https://github.com/JanKallman/EPPlus
[implicit convertions]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/conversions#implicit-conversions
[book-empty]: docs/img/book-empty.svg "Пустая книга"
[sheet-name]: docs/img/sheet-name.svg "Именованные листы"
[box-a1]: docs/img/box-a1.svg "Box A1"
[box-a1-b1]: docs/img/box-a1-b1.svg "Box A1, Box B1"
[box-header]: docs/img/box-header.svg "Box шапки"
[box-header-model]: docs/img/box-header-model.svg "Модель box'а шапки"
[box-plan-fact]: docs/img/box-plan-fact.svg "PlanFact box"
[box-plan-fact-model]: docs/img/box-plan-fact-model.svg "Модель PlanFact box'а"
[s1table.cs]: src/BookFx.Usage/S1Table.cs
[s2style.cs]: src/BookFx.Usage/S2Style.cs
[s3calendar.cs]: src/BookFx.Usage/S3Calendar.cs
[s5protosheet.cs]: src/BookFx.Usage/S5ProtoSheet.cs
[s6protobox.cs]: src/BookFx.Usage/S6ProtoBox.cs
[s7balancesheet.cs]: src/BookFx.Usage/S7BalanceSheet.cs
[s-3-calendar]: docs/img/s-3-calendar-ru.png "Результат S3Calendar.cs"