该页面可以包含自动翻译的文本。

如何布局 PDF 页面

PdfDocumentBuilder.Generate 方法向其 委托提供 Document 类型的对象。 使用该对象的 Pages 方法来构建文档页面。 您必须向该方法提供一个 接受 PageLayout 类型参数的委托。

布置 PDF 页面

如果 PDF 文档中的所有页面都具有相同的布局,则调用该方法一次就足够了。 如果文档中有不同的布局,请多 次调用 Pages 方法。 例如,您可以调用该方法一次来布局封面。 然后再次调用该方法来描述报表主体。

每次调用 Pages 都会创建至少一个页面。 如果没有为其提供内容,则创建的页面可以为空。

本文是有关用于 PDF 生成的 Layout API 的系列文章的一部分。 如果您是 API 新手,请先阅读 Layout API 入门 部分。

Docotic.Pdf 库 9.4.17469-dev 布局附加组件 9.4.17469-dev
回归测试 14,760 通过 NuGet 总下载量 4,447,259

内容槽位

要描述页面布局,请使用预定义的容器。 我也称它们为内容槽。 您可以通过调用 PageLayout 对象的方法来访问这些容器。

共有三个主要插槽:ContentHeaderFooter。 还有两个用于附加内容的插槽:BackgroundForeground。 默认情况下,所有五个容器都是空的,不占用页面空间。 您可以根据需要在插槽之间分配页面 内容。

阅读 容器及其内容物 文章以了解如何使用容器布局页面。

您不会惊讶地知道页眉和页脚内容分别进入 HeaderFooter 插槽。 API 在每个生成的页面上的主要内容 上方和下方重复这些插槽。 Layout API 永远不会在页面之间拆分页眉或页脚内容。 如果页眉或页脚不适合页 面,您将收到 LayoutException

主要内容

主页内容(如图像、表格和文本)进入 Content 槽。 Layout API 自动将该内容拆分为页面。

以下代码将简单文本内容分配给所有主要内容槽。 该代码还设置了插槽的背景颜色。

PdfDocumentBuilder.Create().Generate("pages-main-slots.pdf", doc => doc.Pages(pages => {
    pages.Header()
        .Text("This text goes to the header")
        .BackgroundColor(new PdfRgbColor(66, 135, 245));

    pages.Content()
        .Text("The main content goes in this slot")
        .BackgroundColor(new PdfRgbColor(242, 233, 206));

    pages.Footer()
        .Text("This is the footer contents")
        .BackgroundColor(new PdfRgbColor(194, 192, 188));
}));

检查 pages-main-slots.pdf 中的代码结果。

正如您所看到的,每个插槽仅占据页面的一部分。 确切的区域取决于插槽内的内容。 Header 插槽粘在页面顶部。 Content 槽位在 Header 之后立即开始。 “页脚” 插槽粘在底部。

附加内容

BackgroundForeground 提供可用于水印、叠加层和背景的容 器。 Background 槽中的所有内容都位于页眉、页脚和页面主要内容的下方。 Foreground 槽中的内容涵盖 了添加到页面的所有内容。

这些容器占据了整个页面。 这是这些容器的独特之处。 API 在每个生成的页面上重复其内容。 与页眉和页脚容 器完全相同。

我在上面的代码中添加了一些行来展示如何使用 ForegroundBackground 容器。

PdfDocumentBuilder.Create().Generate("pages-all-slots.pdf", doc => doc.Pages(pages => {
    // ... 

    pages.Background()
        .Background(new PdfRgbColor(208, 227, 204));

    pages.Foreground()
        .Rotate(45)
        .Text(new string(' ', 30) + "Your watermark could go here, in the foreground");
}));

对于 Background 容器,我不提供任何文本或其 他内容。 我只指定背景颜色。 页眉、主要内容和页脚下方的所有内容都将显示绿色阴影。

我旋转 Foreground 容器中的内容并向其中添加 一些文本。 由于前导空格,文本不会覆盖页眉或页脚内容。 所有容器中的内容在页面上都可见。

您可以在 pages-all-slots.pdf 中查看代码的结果。

设置

到目前为止,所有代码片段都集中在构成页面的容器上。 现在是时候考虑如何自定义页面本身,而不是其内容 槽。

要设置页面,请使用 PageLayout 类的方法。 请记住,一个 PageLayout 对象可以描述多个页面。 方法调用将影响您描述的所有页面。

尺寸

最基本的设置可能是页面大小。 您可以使用 Size 方法 来指定页面的预定义尺寸之一。 有所有常见尺寸,如 A4、Ledger 或 Monarch 信封。

您还可以选择指定页面的方向。 可以通过提供以磅为单位的宽度和高度来设置自定义页面大小。

边距

页边距可能有助于提高页面的可读性、美观性和整体构图。

使用 Margin 方法将所有边距设置为相同的点值。 使 用 MarginVerticalMarginHorizontal 方法仅设置垂直或水平 边距。 使用 MarginLeft/Top/Right/Bottom 方法独立指定每个边距。

文字样式

Layout API 提供了 TextStyle 类来创建文本样式。 您可以创 建样式并将其应用到文本以实现所需的外观。

在某些情况下,页面上的大部分文本都使用相同的样式。 您可以将该样式设置为页面的默认文本样式。 默认样 式会影响主要内容槽中的所有文本。 但您可以覆盖某些元素的默认样式。 只需对看起来不同的文本应用另一种 样式即可。

PdfDocumentBuilder.Create().Generate("pages-text-styles.pdf", doc =>
{
    var defaultStyle = TextStyle.Parent.FontSize(30);
    var tightSpacing = TextStyle.Parent.LetterSpacing(-0.1);

    doc.Pages(pages =>
    {
        pages.TextStyle(defaultStyle);

        pages.Content().Text(t =>
        {
            t.Line("This line uses the default text style.");
            t.Line("This line uses a tight letter spacing.").Style(tightSpacing);
            t.Line("This line uses the default text style, again.");
        });
    });
});

您可以在 pages-text-styles.pdf 中查看代码的结 果。

请注意,您可以使用 Document.Typography 方法设 置文档范围的文本样式。 Typography 类中的每个属性都定义 用例的样式。 这些样式会覆盖 PageLayout.TextStyle 方法指定的样式。 例 如,Typography.Body 属性会覆盖 Content 容器中文本的默认样式。

内容方向

有些语言是从右向左书写的。 Layout API 可以很好地处理这些语言的文本。 但您需要明确指定文本方向。

如果页面上的大部分文本都是 RTL 语言,则可以将从右到左设置为页面的默认内容方向。 您将能够为页面中的 任何容器指定不同的方向。

PdfDocumentBuilder.Create().Generate("pages-content-direction.pdf", doc =>
{
    var defaultTextStyle = doc.TextStyleWithFont(SystemFont.Family("Calibri"));

    doc.Pages(pages =>
    {
        pages.Size(PdfPaperSize.A6).TextStyle(defaultTextStyle);

        pages.ContentFromRightToLeft();

        pages.Content().Column(column =>
        {
            column.Item()
                .ContentFromLeftToRight()
                .Text("There are languages written from right to left.");

            column.Item()
                .Text("هناك لغات تكتب من اليمين إلى اليسار.");

            column.Item()
                .Text("יש שפות שנכתבות מימין לשמאל.");
        });
    });
});

在上面的代码中,我将从右到左设置为默认内容方向。 对于包含英语版本短语的容器,我将方向更改为从左到 右。 您可以在 pages-content-direction.pdf 中查看代码的结果。

页码

生成 PDF 时,Layout API 会自动计算当前页码。 它还计算文档中的总页数。 您可以通过调用任何文本容器的 CurrentPageNumberPageCount 方法来获取数字。 无论容器位于页 眉、页脚还是主要内容槽中。

PdfDocumentBuilder.Create().Generate("pages-page-numbers.pdf", doc => doc.Pages(pages =>
{
    pages.Content().Text(t =>
    {
        t.Span("This line is on page ");
        t.CurrentPageNumber();
        t.Line();
        t.Line("Check the footer.");
    });

    pages.Footer().Row(r =>
    {
        r.AutoItem().Text("Created with Docotic.Pdf Layout API");

        r.RelativeItem(2).Text(t =>
        {
            t.AlignRight();

            t.Span("Page ");
            t.CurrentPageNumber();
            t.Span(" of ");
            t.PageCount();
        });
    });
}));

代码的结果在 pages-page-numbers.pdf 中。

这两种方法都会返回 TextPageNumber,您可以使用它来 格式化数字。

向 PDF 文档添加页眉和页脚 示例演示如何将自定义格式应用于页码。

示例代码

我们有一些示例应用程序,更详细地涵盖了上述功能。 请花一些时间检查一下。