このページには自動翻訳されたテキストを含めることができます。

複合コンテナ

複雑なコンテナは、コンテンツの構造化と整理に重要な役割を果たします。適切なコンテナを使用すること で、テキストや画像をユーザーフレンドリーな方法で簡単に表示できます。

単純なテキスト コンテナーと画像コンテナーのみを使用してドキュメントを作成することは確かに可能です。 ただし、単純なコンテナーのみでは実装が困難または不可能な要件があります。複合コンテナーはそのような 場合に役立ちます。また、複雑なコンテナーは、少ないコードで目的を達成するのに役立ちます。

複合コンテナ

LayoutContainer クラスのメソッドを使用し て、RowColumn な どの複雑なコンテナーをドキュメント ページに追加します。これらのコンテナーを使用して、グリッドやリス トなどの他のコンテナーを実装できます。あまり一般的ではないが、それでも重要なケースのため に、Inlined メソッドと Layers メソッドもあります。

この記事は、PDF 生成のための Layout API に関するシリーズの一部です。 API を初めて使用する場合は、ま ず Layout API の使用開始 の部分をお読みください。

Docotic.Pdf ライブラリ 9.5.17548-dev レイアウトアドオン 9.5.17548-dev
回帰テスト 14,726人が合格 NuGet の合計ダウンロード数 4,514,921

Row

Row コンテナは、1 行に水平に並べられたアイテムを配置するス ペースを提供します。行内の各アイテムはコンテナです。つまり、異なるタイプのコンテンツを 1 行に配置で きます。Spacing メソッドを使用して、アイテム間の間隔 を指定できます。

行内のすべてのアイテムの高さは同じです。ライブラリは、最も高いアイテムの高さを行の高さとして使用し ます。アイテムの幅を指定する方法は 3 つあります。アイテムを作成するときに、そのうちの 1 つを選択す る必要があります。行には、さまざまな方法で作成されたアイテムを含めることができます。

Row.AutoItem メソッドは、幅が明示的に指定されていな いアイテムを作成します。このようなアイテムの場合、ライブラリはコンテンツの固有のサイズを計算しま す。計算されたコンテンツの幅がアイテムの幅になります。AutoItem で作成されたアイテムは長い行を折り 返さないことに注意してください。

正確なポイント数に等しい幅を持つアイテムを作成するに は、ConstantItem メソッドを使用します。

RelativeItem は、行内のアイテムの正確な幅がわか らず、固有のサイズを使用したくない場合に便利です。代わりに、行内のアイテムの相対的な幅を指定できま す。このメソッドは、アイテムが占める部分の数を受け入れます。部分の合計数は、この行のすべての RelativeItem 呼び出しのすべての数値の合計です。

たとえば、RelativeItem 呼び出しが 1 つある場合、数は重要ではありません。アイテムは使用可能な幅全 体を占めます。アイテムが 2 つ以上ある場合、数によって比率が定義されます。

row.RelativeItem(2)
row.RelativeItem(3)
row.RelativeItem(1)

上記のコードで作成されたすべてのアイテムは、6 つの部分 (2 + 3 + 1 = 6) を占めます。個々のアイテム は、それぞれ 6 つのうち 2 つ、6 つのうち 3 つ、6 つのうち 1 つの部分を占めます。

Layout API は、次の式を使用して 1 つのパーツの幅を計算します。

PartWidth = (RowWidth - AutoWidth - ConstantWidth) / TotalParts

ここで:
RowWidth = 行コンテナの幅
AutoWidth = AutoItem メソッドで作成されたすべての項目の幅
ConstantWidth = ConstantItem メソッドで作成されたすべての項目の幅

以下は、3 種類すべての項目を含む行を作成する例です。

var monthNames = DateTimeFormatInfo.InvariantInfo.MonthNames;
var groups = new[]
{
    string.Join(", ", monthNames.Take(4)),
    string.Join(", ", monthNames.Skip(4).Take(4)),
    string.Join(", ", monthNames.Skip(8).Take(4)),
};

PdfDocumentBuilder.Create().Generate("compounds-row.pdf", doc => doc.Pages(page =>
{
    page.Content()
        .Padding(20)
        .MinimalBox()
        .Row(row =>
        {
            row.ConstantItem(100)
                .Background(new PdfRgbColor(187, 237, 237))
                .Text("100 points wide");

            for (int i = 0; i < groups.Length; i++)
            {
                row.AutoItem().LineVertical(0.1);

                var numberOfParts = groups.Length - i + 1;
                row.RelativeItem(numberOfParts)
                    .PaddingHorizontal(5)
                    .Text(t =>
                    {
                        t.Line($"{numberOfParts} parts wide");
                        t.Line();
                        t.Line(groups[i]);
                    });
            }
        });
}));

コードの結果は compounds-row.pdf で確認できます。

Column

アイテムを縦に並べるには、Column コンテナを使用します。列 内の各アイテムはコンテナです。このため、1 つの列に異なるタイプのコンテンツを配置できます。

各項目の幅は列の幅と同じです。各項目の高さは、項目のコンテンツとプロパティによって異なりま す。Column コンテナーはページングをサポートしているため、Layout アドオンは列の項目を複数のページ にレンダリングできます。

デフォルトでは、Column コンテナーにはヘッダーまたはフッターのコンテンツがありません。対応するコン テナーにアクセスして設定するには、Header メソッドと Footer メソッドを使用します。列項目が複数のページに わたる場合、ライブラリは各ページでヘッダーとフッターの両方を繰り返します。

列項目間に垂直方向のスペースを追加するに は、Spacing メソッドを使用します。ライブラリはヘッ ダーと最初の項目の間にスペースを適用しないことに注意してください。また、ライブラリはフッターの前に スペースを追加しません。

PdfDocumentBuilder.Create().Generate("compounds-column.pdf", doc => doc.Pages(page =>
{
    page.Size(PdfPaperSize.A6);

    page.Content()
        .Padding(20)
        .Column(column =>
        {
            column.Header()
                .Background(new PdfRgbColor(187, 237, 237))
                .Padding(5)
                .Text("Month names");

            for (int i = 0; i < 12; i++)
            {
                column.Item().Background(
                    new PdfGrayColor(i % 2 == 0 ? 90 : 100))
                    .Padding(5)
                    .Text(DateTimeFormatInfo.InvariantInfo.MonthNames[i]);
            }

            column.Footer().LineHorizontal(1);
        });
}));

コードの結果は compounds-column.pdf で確認できま す。

グリッド

グリッド レイアウトは、アイテムを列と行に整理します。この点では、グリッドはテーブルに似ていま す。Layout API は、グリッド用の特別なコンテナー タイプを提供しませ ん。Column コンテナーと Row コンテナーを使用して、グリッド レイアウトを実装できます。

グリッドを列、その各項目を行と考えると分かりやすいでしょう。Column コンテナと Row コンテナの両 方で、項目間の間隔を設定できます。必要に応じて、ヘッダーとフッターを追加できます。

各行は独立したレイアウトを持つことができます。各行には異なる数のアイテムを含めることができます。ア イテムの幅と高さはそれぞれ異なっています。行内のアイテムの前、後、または間に余分なスペースを追加す ることができます。これには、コンテンツや装飾のないアイテムを使用します。

var blue = new PdfRgbColor(187, 237, 237);
var darkerBlue = blue.Darken(50);
PdfDocumentBuilder.Create().Generate("compounds-grid.pdf", doc => doc.Pages(page =>
{
    page.Size(300, 200);

    page.Content().Padding(15).Column(column =>
    {
        column.Spacing(10);

        column.Item().Row(row =>
        {
            row.Spacing(10);

            row.ConstantItem(100).Background(darkerBlue).Height(40);
            row.RelativeItem(4).Background(blue);
        });

        column.Item().Row(row =>
        {
            row.Spacing(10);

            row.RelativeItem(2).Background(blue).Height(60);
            row.RelativeItem(1);
            row.RelativeItem(2).Background(blue);
        });

        column.Item().Row(row =>
        {
            row.Spacing(10);

            row.RelativeItem(1).Background(blue).Height(50);
            row.RelativeItem(3).Background(blue);
            row.ConstantItem(50).Background(darkerBlue);
        });
    });
}));

コードの結果は compounds-grid.pdf で確認できます。

リスト

リストは、情報を簡潔なポイントに分割することで読みやすさを向上させます。リスト項目には、テキストの 横に数字、箇条書き、その他の記号を表示できます。Column お よび Row コンテナーを使用して、リストレイアウトを簡単に実装で きます。Layout API は、リスト用の特別なコンテナー タイプを提供していません。

季節ごとに月のリストを作成するサンプル コードを確認してください。リストにはヘッダーがあることに注意 してください。項目に次の行に折り返される可能性のあるテキストが含まれている場合は、項目のテキスト部 分に RelativeItem メソッドまたは ConstantItemメソッドのいずれかを使用します。

var monthNames = DateTimeFormatInfo.InvariantInfo.MonthNames.ToList();
monthNames.Insert(0, monthNames[11]);

PdfDocumentBuilder.Create().Generate("compounds-list.pdf", doc => doc.Pages(page =>
{
    page.Size(150, 200);

    page.Content().Padding(5).Column(column =>
    {
        column.Header()
            .Text("Months by seasons:")
            .Style(TextStyle.Parent.Underline());

        for (int i = 0; i < 4; i++)
        {
            var season = string.Join(", ", monthNames.Skip(i * 3).Take(3));
            column.Item().Row(row =>
            {
                row.Spacing(2);

                row.AutoItem().Text("•");
                row.RelativeItem().Text(season);
            });
        }
    });
}));

コードの結果は compounds-list.pdf で確認できます。

Table

テーブル レイアウトは、アイテムを列と行に整理します。Table コンテナー タイプは、広範な機能セットを提供し、最も複雑なケースでも役立ちます。Table コンテナ の記 事ですべての機能についてお読みください。

InlineContainer

コンテナーに他のコンテナーのコレクションを追加できます。まず、LayoutContainer.Inlined メソッドを 呼び出します。次に、提供されている InlineContainerItem メソッドを呼び出して、子コンテナーを追 加します。

Layout アドオンは、コンテナーを次々に一列に配置します。アイテムを配置するスペースがない場合、ライブ ラリは新しい行を開始します。アイテム間にスペースを追加するに は、Spacing/Horizo​​ntalSpacing/VerticalSpacing メソッドを使用します。

配置メソッドを使用して、コンテナー内のアイテムの位置に影響を与えることができます。 AlignTop/AlignMiddle/AlignBottom メソッドは、アイテムを垂直方向に配置します。 水平方向に は、AlignLeft/AlignCenter/AlignRight/AlignJustify メソッドを使用します。

特別なケースがあります。アイテムを水平に揃える AlignSpaceAround メソッドです。 また、最初のアイテムの前と最後のアイテムの後に余分なスペースを追加します。

var orange = new PdfRgbColor(250, 123, 5);
var brown = orange.Darken(50);
var itemProps = new (int Width, PdfColor Color)[] {
    (20, orange), (30, orange), (50, brown), (50, orange), (50, orange),
    (30, orange), (20, brown), (30, orange), (50, brown), (10, brown)
};

PdfDocumentBuilder.Create().Generate("compounds-inlined.pdf", doc => doc.Pages(page =>
{
    page.Size(150, 120);

    page.Content().Inlined(c =>
    {
        c.Spacing(5);

        foreach (var (Width, Color) in itemProps)
            c.Item().Height(30).Width(Width).Background(Color);
    });
}));

コードの結果は compounds-inlined.pdf で確認でき ます。

LayerContainer

メイン ページ コンテンツの下または上にコンテンツを配置する必要がある場合があります。明らかな使用例 は、PDF ページの上に透かしを追加することです。

まず、LayoutContainer.Layers メソッドを呼 び出して LayerContainer オブジェクトを取得します。 オブジェクトを取得したら、レイヤーの追加を開始できま す。Layer メソッドを呼び出すと、セカンダリ レイヤーが追加されます。メイン コンテンツ レイヤーを追加するに は、PrimaryLayer メソッドを呼び出しま す。プライマリ レイヤーは 1 つだけ追加する必要があります。

Layout API は、レイヤーを作成した順序でレイヤーを構成します。プライマリ レイヤーの前に追加されたレ イヤーは背景になります。プライマリ レイヤーの後に追加されたすべてのレイヤーは、メイン コンテンツの 上になります。コンテナーは、メイン コンテンツが占めるすべてのページでセカンダリ レイヤーを繰り返し ます。

PDF ページに透かしを追加する方法のサンプル コードを示します。

PdfDocumentBuilder.Create().Generate("compounds-layers.pdf", doc => doc.Pages(page =>
{
    var largeRedText = TextStyle.Parent.FontSize(48)
        .FontColor(new PdfRgbColor(235, 64, 52));

    page.Size(400, 250);

    page.Content()
        .Padding(25)
        .Layers(layers =>
        {
            layers.Layer()
                .AlignCenter()
                .Text(text => text.CurrentPageNumber().Style(largeRedText));

            layers.PrimaryLayer()
                .Background(new PdfGrayColor(85), 65)
                .Padding(25)
                .Text(new string('_', 790));

            layers.Layer()
                .AlignCenter()
                .AlignMiddle()
                .Text("Watermark")
                .Style(largeRedText);
        });
}));

コードの結果は compounds-layers.pdf で確認できま す。

透かし

一般的な要件の 1 つは、PDF に透かしを追加することです。この要件はさまざまな理由で発生します。PDF に 透かしを追加して、所有権を識別したり、PDF 内の情報の機密性や機密性を指摘したりできます。

PDF に透かしを入れる 1 つの方法は、レイヤーを使用することです。前のセクションの例を参照してくださ い。別の方法を紹介します。

ページの背景と前景のコンテナを使用して PDF に透かしを入れます。Layout アドオンは、これらのコンテナ を次のページで繰り返します。主要なドキュメント コンテンツを含むすべてのページにも、背景と前景のコン テナが含まれます。これにより、これらのコンテナがこのタスクに適しています。

まず、背景コンテナー に画像を追加します。同 じ方法で PDF にロゴを追加できます。画像はページ コンテンツの背後に表示されます。ドキュメントの何 ページで背景画像が使用されるかは関係ありません。APIは、生成された PDF に画像バイトのコピーを 1 つだ け追加します。

主要なドキュメント コンテンツは何でも構いません。このサンプル コードでは、有名な Lorem Ipsum テキス トを使用します。

テキストの透かしは フォアグラウンド コンテ ナー に入ります。テキスト自体は何でもよく、 任意の色やフォントを使用できます。私は、大きなサイズの半透明の赤い文字で描かれた回転したテキストを 使用しました。

サンプル コードは、サンプル コードのリポジトリから画像とテキストの両方を非同期的にダウンロードしま す。もちろん、ローカル画像を使用したり、ファイルからテキストを読み取ったりすることもできます。

var urlPrefix =
    "https://raw.githubusercontent.com/BitMiracle/Docotic.Pdf.Samples/master/Samples/Sample%20Data/";

using var client = new HttpClient();
using var imageResponse = await client.GetAsync(urlPrefix + "watermark-background.png");
using var imageStream = await imageResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);

var loremIpsum = string.Empty;
using (var textResponse = await client.GetAsync(urlPrefix + "lorem-ipsum.txt"))
     loremIpsum = await textResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

PdfDocumentBuilder.Create().Generate("compounds-watermarks.pdf", doc =>
{
    var image = doc.Image(imageStream);

    doc.Pages(page =>
    {
        page.Size(400, 250);

        page.Background()
            .AlignMiddle()
            .Image(image);

        page.Content()
            .Padding(25)
            .Text(loremIpsum);

        var largeRedText = TextStyle.Parent.FontSize(48)
            .FontColor(new PdfRgbColor(235, 64, 52), 50);
        page.Foreground()
            .Rotate(-30)
            .Translate(-50, 180)
            .Text("DO NOT COPY")
            .Style(largeRedText);
    });
});

コードの結果は compounds-watermarks.pdf で確 認できます。

サンプル コード

上記の機能についてさらに詳しく説明したサンプル アプリがいくつかあります。ぜひご確認ください。