Эта страница может содержать автоматически переведенный текст.
Контейнеры и их содержимое
Документ представляет собой набор страниц. Каждая страница, в свою очередь, представляет собой набор фрагментов контента. Как вы, возможно, уже знаете, PageLayout предоставляет контейнеры для основного и дополнительного контента. Но что делать с этими контейнерами?
Контейнеры помогают организовать контент на страницах. Все, что вы помещаете на страницу, должно попасть в контейнер. Если содержимое достаточно велико, контейнер может занимать место более чем на одной странице.
Вы можете поместить в контейнер текст или изображение. В целях выравнивания и позиционирования вы можете поместить контейнер внутрь другого контейнера. Существуют контейнеры, в которых можно разместить более одного фрагмента контента.
Контейнеры на странице представлены объектами класса LayoutContainer. Используйте этот класс для настройки размера, положения, содержимого и процесса рендеринга ваших контейнеров.
Эта статья - часть серии статей про Layout API для генерации PDF-файлов. Если вы новичок в работе с API, то сначала прочитайте часть Начало работы с Layout API.
9.5.17615-dev 9.5.17615-dev14,813 прошло Всего загрузок NuGet 4,924,084
Принцип работы контейнеров
Вы начинаете с получения контейнера. Например, вызвав метод PageLayout.Content. Этот метод вернет контейнер, который не занимает места и не имеет содержимого или свойств. Используйте методы класса LayoutContainer для настройки контейнера.
Очень важно понимать, что все методы LayoutContainer
помещают контент в контейнер. Когда вы
добавляете в контейнер текст, это ожидаемо. Но что становится содержимым, когда вы устанавливаете
отступ или ширину?
Когда вы устанавливаете свойство контейнера, библиотека создает новый контейнер с указанным свойством. Новый контейнер становится содержимым исходного контейнера. Библиотека возвращает вложенный контейнер как результат метода.
Свойства вложенных контейнеров влияют на родительские контейнеры и наоборот. Например, ширина вложенного контейнера влияет на размер родительского контейнера. Стиль текста родительского контейнера по умолчанию влияет на текст во вложенных контейнерах. Дополнение Layout использует иерархию контейнеров и их свойств для создания результирующего макета.
Результат следующего кода может вас удивить, но, пожалуйста, потратьте некоторое время на его анализ. Код иллюстрирует, как работают вложенные контейнеры.
PdfDocumentBuilder.Create().Generate("containers-how.pdf", doc => doc.Pages(page =>
{
page.Size(150, 150);
page.Content()
.Background(new PdfRgbColor(235, 64, 52)) // красный
.PaddingTop(50)
.Background(new PdfRgbColor(187, 237, 237)) // голубой
.PaddingRight(50)
.Background(new PdfRgbColor(15, 130, 9)) // зеленый
.PaddingBottom(50)
.Background(new PdfRgbColor(250, 123, 5)) // оранжевый
.PaddingLeft(50)
.Background(new PdfRgbColor(204, 204, 204)); // серый
}));
Украшение
Дизайн документа включает в себя больше, чем просто организацию текста и изображений. Правильно разработанный документ создает не только эффективную, но и визуально привлекательную коммуникацию.
С помощью Layout API вы можете применить цвет фона к любому контейнеру. Это помогает установить иерархию внутри вашего контента. Вы также можете определить границы, применяя рамки. Используйте вертикальные и горизонтальные линии для разделения элементов контента.
PdfDocumentBuilder.Create().Generate("containers-decor.pdf", doc => doc.Pages(page =>
{
page.Size(150, 150);
page.Content()
.Background(new PdfRgbColor(250, 123, 5))
.Border(b =>
{
b.Color(new PdfGrayColor(0), 50);
b.Thickness(15);
})
.PaddingTop(74)
.LineHorizontal(2)
.Color(new PdfCmykColor(73, 45, 0, 4))
.DashPattern(new PdfDashPattern(new double[] { 8, 2 }));
}));
API поддерживает непрозрачные и полупрозрачные цвета в цветовых пространствах Gray, RGB и CMYK. Помимо сплошных линий, Layout API поддерживает линии, в которых используются пунктирные узоры.
Результат работы приведенного выше кода находится в файле containers-decor.pdf.
Содержимое
Давайте посмотрим, что класс LayoutContainer предоставляет для организации содержимого.
Text
Чтобы добавить текст в контейнер, используйте один из методов Text.
Если весь текст использует один и тот же стиль, используйте простую сокращенную версию метода. Эта версия принимает строку и возвращает объект TextSpan. Вы можете использовать результат для настройки стиля текста.
Существует еще одна версия метода Text
, которая принимает делегат типа Action<TextContainer>
.
Используйте эту версию, чтобы иметь фразменты с разными стилями в одном блоке текста.
TextContainer предоставляет методы для вставки
изображений и других элементов между текстовыми фрагментами. Есть и другие расширенные функции,
такие как возможность устанавливать расстояние между абзацами.
PdfDocumentBuilder.Create().Generate("containers-text.pdf", doc => doc.Pages(page =>
{
page.Header().Text("This is a simple text span");
page.Content().Text(t =>
{
t.Span("This line contains ");
t.Span("some underlined text").Style(TextStyle.Parent.Underline());
});
}));
Вы можете увидеть результат выполнения кода в containers-text.pdf.
Image
API Layout предоставляет методы для создания объектов Image
из изображений в файле или потоке. Любой объект Image
может служить содержимым контейнера. Вы
можете использовать один и тот же объект Image
в нескольких контейнерах. Существуют различные
режимы содержимого, которые влияют на то, как изображение будет выглядеть внутри контейнера.
Библиотека может загружать изображения только в растровых форматах: PNG, JPEG, JPEG 2000, BMP, GIF и TIFF.
PdfDocumentBuilder.Create().Generate("containers-image.pdf", doc =>
{
var imageFile = new FileInfo(@"path-to-image.jpg");
var image = doc.Image(imageFile);
doc.Pages(pages =>
{
pages.Size(image.Width, image.Height);
pages.Content().Image(image, ImageContentMode.FitArea);
});
});
Column
Столбцы предоставляют место для неограниченного количества элементов, расположенных друг над другом. Внутри столбца можно использовать элементы любого типа. Например, столбец может содержать изображения и текстовые элементы. Ширина каждого элемента равна ширине столбца. Высота каждого элемента зависит от его содержимого и свойств.
PdfDocumentBuilder.Create().Generate("containers-column.pdf", doc => doc.Pages(page =>
{
page.Content().Column(c =>
{
for (int i = 0; i < 10; i++)
{
PdfColor color = i % 2 == 0
? new PdfRgbColor(187, 237, 237)
: new PdfGrayColor(66);
c.Item().Background(color).Height(10 + i * 3);
}
});
}));
Вы можете увидеть результат выполнения кода в containers-column.pdf.
Прочтите статью Составные контейнеры для получения подробной информации о функциях контейнера Column.
Row
Контейнеры Row помогают организовать неограниченное количество элементов в ряд. Каждый элемент в ряду является контейнером. Благодаря этому вы можете размещать контент разных типов в ряд.
PdfDocumentBuilder.Create().Generate("containers-row.pdf", doc => doc.Pages(page =>
{
var rowItems = new[] { "three", "two", "one" };
page.Content().Row(row =>
{
for (int index = 0; index < rowItems.Length; index++)
{
row.AutoItem().Text(rowItems[index]);
if (index != rowItems.Length - 1)
row.AutoItem().PaddingHorizontal(10).LineVertical(0.5);
}
});
}));
Вы можете увидеть результат выполнения кода в containers-row.pdf.
Статья Составные контейнеры содержит подробную информацию о контейнерах Row
.
Table
Используйте контейнеры Table для размещения самых сложных данных. Начните с определения хотя бы одного столбца, а затем заполните столбцы и строки, вызвав метод Cell несколько раз.
Таблицы могут иметь верхний и нижний колонтитулы. Ячейки в таблице могут охватывать более одного столбца и/или строки. Вот код, который добавляет простую таблицу.
PdfDocumentBuilder.Create().Generate("containers-table.pdf", doc => doc.Pages(page =>
{
page.Content().Table(t =>
{
t.Columns(c =>
{
for (int i = 0; i < 4; ++i)
c.ConstantColumn(50);
});
for (int i = 0; i < 16; i++)
{
t.Cell()
.Border(b => b.Thickness(0.5))
.PaddingHorizontal(10)
.Text($"{i + 1}");
}
});
}));
Результат выполнения кода находится в containers-table.pdf.
Обо всех возможностях контейнера Table
читайте в статье Контейнер Table.
Inlined
Контейнер InlineContainer позволяет удобно заполнить область элементами из коллекции контейнеров. Вы просто добавляете элементы один за другим, а библиотека ставит их в ряд один за другим. Когда места для размещения нового элемента нет, библиотека начинает новую строку.
Дополнительную информацию о контейнерах InlineContainer
можно найти в статье Составные контейнеры.
Layers
Бывают случаи, когда лучше размещать контент на нескольких слоях. Контейнер LayerContainer служит именно этой цели. Вы должны определить ровно один основной слой и любое количество неосновных. Layout API будет компоновать слои в том же порядке, в котором вы их создаете.
Прочтите Составные контейнеры для получения более подробной информации о типе LayerContainer
.
Element
Это особый вид контента. Вы можете создать элемент динамически и поместить результат в контейнер.
Динамически создаваемые элементы могут иметь макет, который зависит от номера страницы, размера и других свойств.