이 페이지에는 자동 번역된 텍스트가 포함될 수 있습니다.

컨테이너의 크기, 위치 및 렌더링

내용은 문서에서 가장 중요한 부분입니다. 그것에 대해서는 의심의 여지가 없습니다. 또 다른 중요한 부분은 명확하고 전문적이며 효과적인 의사소통을 생성하는 형식입니다. 적절한 형식의 문서는 시각적으로 매력적이고 읽기 쉽고 탐색하기 쉽습니다.

컨테이너를 사용하여 콘텐츠를 구성하는 방법을 이미 알고 있을 수도 있습니다. 배경색을 적용하는 방법도 설명되어 있습니다. 이 문서에서는 컨테이너의 크기와 위치를 지정하는 방법을 설명합니다. 또한 콘텐츠의 조건부 렌더링과 같은 고급 기능도 다룹니다. 오른쪽에서 왼쪽으로 콘텐츠 방향 지원에 대한 정보가 있습니다.

컨테이너 포지셔닝

LayoutContainer 클래스는 컨테이너를 전문적으로 정렬하는 데 필요한 모든 것을 제공합니다. 패딩과 정렬을 적용하면 사용자에게 긍정적인 인상을 주는 문서를 만들 수 있습니다.

이 기사는 PDF 생성을 위한 Layout API 에 관한 시리즈의 일부입니다. API 를 처음 사용하는 경우 Layout API 시작하기 부분을 먼저 읽어보세요.

Docotic.Pdf 라이브러리 9.4.17469-dev 레이아웃 애드온 9.4.17469-dev
회귀 테스트 14,760건의 테스트 통과 총 NuGet 다운로드 4,447,259

크기

기본적으로 컨테이너는 콘텐츠에 필요한 가장 작은 영역을 차지합니다. 다르게 말하면, 컨테이너의 크기는 콘텐츠의 본질적인 크기와 같습니다.

이미지 파일 자체의 크기에 따라 결정되는 이미지의 고유 크기입니다. 텍스트 범위의 기본 크기는 해당 범위의 모든 문자 모양을 포함하는 영역의 크기입니다.

Column 이나 Table 과 같은 복합 컨테이너의 크기는 컨테이너 부분의 크기에 따라 달라집니다.

Width & Height

WidthHeight 메소드를 사용하여 컨테이너의 정확한 너비와 높이를 지정할 수 있습니다. 이는 자리 표시자 컨테이너에 매우 편리합니다.

정확한 크기는 이미지에도 적합합니다. 이는 Layout API 가 ImageContentMode 에 따라 컨테이너에 맞거나 채우도록 크기를 조정하기 때문입니다.

복합 컨테이너와 텍스트가 포함된 컨테이너의 정확한 크기에 주의해야 합니다. 제공된 크기에 콘텐츠를 맞출 수 없는 경우 LayoutException 이 발생합니다.

너비나 높이에만 제약 조건을 설정하려는 경우가 있습니다. MinWidth, MinHeight, MaxWidthMaxHeight 메서드를 사용하여 제약 조건을 설정할 수 있습니다.

제약 조건을 충족할 수 없는 경우 라이브러리는 LayoutException 을 발생시킵니다.

Extend

컨테이너는 사용 가능한 최대 공간을 차지하도록 자체 확장할 수 있습니다. 이는 정확한 크기나 크기 제한을 모를 때 유용합니다.

컨테이너가 수평 방향으로만 사용 가능한 모든 공간을 차지하도록 하려면 ExtendHorizontal 메서드를 사용하세요. ExtendVertical 은 컨테이너를 수직 방향으로만 확장하려는 경우에 유용합니다. Extend 메서드를 사용하면 컨테이너가 양방향에서 사용 가능한 모든 공간을 차지하게 됩니다.

var gray = new PdfGrayColor(75);
var text = "Content goes here";
var size = new PdfSize(150, 50);

PdfDocumentBuilder.Create().Generate("positioning-extend.pdf", doc =>
{
    for (int i = 0; i < 4; i++)
    {
        doc.Pages(page =>
        {
            page.Size(size);
            page.Content().Row(r =>
            {
                var container = r.AutoItem().Background(gray);
                switch (i)
                {
                    case 0:
                        container.Text(text);
                        break;

                    case 1:
                        container.ExtendHorizontal().Text(text);
                        break;

                    case 2:
                        container.ExtendVertical().Text(text);
                        break;

                    case 3:
                        container.Extend().Text(text);
                        break;
                }
            });
        });
    }
});

위 코드의 결과는 positioning-extend.pdf 에 있습니다. 보시다시피, 4개의 페이지 각각에는 회색 배경에 동일한 텍스트가 포함되어 있습니다. 하지만 페이지마다 컨테이너의 크기가 다릅니다.

MinimalBox

LayoutContainerMinimalBox 메서드를 제공합니다. 이는 Extend 메소드와는 정반대입니다. MinimalBox 는 콘텐츠에 필요한 최소한의 공간만 사용하는 중첩 컨테이너를 생성합니다.

var gray = new PdfGrayColor(75);
var size = new PdfSize(150, 50);

PdfDocumentBuilder.Create().Generate("positioning-minimalbox.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(size);
        page.Content().MinimalBox().Background(gray).Text("I don't want more space");
    });

    doc.Pages(page =>
    {
        page.Size(size);
        page.Content().Background(gray).Text("I'll take everything");
    });
});

위 코드의 결과는 positioning-minimalbox.pdf 에 있습니다. MinimalBox 호출로 인해 첫 페이지의 텍스트는 필요한 공간만 차지합니다. 두 번째 페이지에서는 텍스트가 페이지 전체를 덮습니다.

Scale

컨테이너의 모든 콘텐츠 크기를 조정할 수 있습니다. Scale 방법은 가로 및 세로 방향 모두에 콘텐츠에 영향을 미칩니다. 콘텐츠를 한 방향으로만 변경하려면 ScaleHorizontal 또는 ScaleVertical 방법을 사용하세요. 마지막 두 가지 방법은 콘텐츠의 종횡비를 유지하지 않습니다.

1보다 작은 배율 값은 컨테이너가 차지하는 영역을 줄입니다. 1보다 큰 값은 면적을 증가시킵니다. 컨테이너의 콘텐츠를 뒤집으려면 음수 배율 값을 사용하세요. 예를 들어 ScaleVertical(-1) 을 사용하면 원본 콘텐츠가 거꾸로 뒤집힌 버전이 됩니다.

PdfDocumentBuilder.Create().Generate("positioning-scale.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content()
            .MinimalBox()
            .Column(column =>
            {
                var scales = new[] { 0.5f, 0.75f, 1, 1.3f, 1.5f };

                foreach (var scale in scales)
                {
                    var percent = (int)(scale * 100);
                    column.Item()
                        .Scale(scale)
                        .Text(FormattableString.Invariant($"Scale equals {scale} ({percent}%)."))
                            .FontSize(20);

                    column.Item().LineHorizontal(0.5);
                }
            });
    });
});

위 코드의 결과는 positioning-scale.pdf 에 있습니다.

ScaleToFit

사용 가능한 공간에 맞게 콘텐츠를 축소할 수 있습니다. 예를 들어 사람의 이름이나 주소를 출력하는 고정된 영역이 있는 경우입니다. 물론 이름이 긴 경우에는 면적을 늘릴 수 있습니다. 그러나 더 쉬운 접근 방식은 텍스트 크기를 약간 줄이는 것입니다. 콘텐츠의 크기를 줄이려면 ScaleToFit 메서드를 사용하세요.

ScaleToFit 은 콘텐츠의 가로 세로 비율을 유지합니다. 이 방법은 결코 콘텐츠를 더 크게 만들지 않습니다. 이 방법은 반복 계산을 수행한다는 점에 유의하십시오. 이로 인해 PDF 생성 프로세스가 느려질 수 있습니다.

PdfDocumentBuilder.Create().Generate("positioning-scaletofit.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().Column(column =>
        {
            for (int i = 0; i < 5; i++)
            {
                column.Item()
                    .Width(230 - 20 * i)
                    .Height(20)
                    .ScaleToFit()
                    .Border(b => b.Thickness(0.5))
                    .Text(" This text should fit into the changing width.");
            }
        });
    });
});

위 코드의 결과는 positioning-scaletofit.pdf 에 있습니다.

AspectRatio

종횡비는 컨테이너의 너비와 높이 사이의 비례 관계를 정의합니다. 컨테이너의 가로 세로 비율을 확인하려면 너비를 높이로 나눕니다.

컨테이너의 가로 세로 비율을 지정하려면 AspectRatio 메서드를 사용하세요. 다양한 레이아웃이나 페이지 크기에 맞게 재사용 가능한 컨테이너를 디자인할 때 도움이 됩니다.

PdfDocumentBuilder.Create().Generate("positioning-aspectratio.pdf", doc =>
{
    var ratios = new double[] { 0.25, 0.5, 1, 2 };
    foreach (var ratio in ratios)
    {
        var ratioText = ratio.ToString(CultureInfo.InvariantCulture);
        doc.Pages(page =>
        {
            page.Size(200, 200);
            page.Content().Column(column =>
            {
                column.Item()
                    .AspectRatio(ratio)
                    .Background(new PdfGrayColor(75))
                    .Text($"Width / Heigth = {ratioText}");
            });
        });
    }
});

위 코드의 결과는 positioning-aspectratio.pdf 에 있습니다.

이 메소드에는 AspectRatioMode 유형의 선택적 매개변수가 있습니다. 이 매개변수를 사용하여 종횡비를 유지하면서 콘텐츠의 크기를 조정하는 방법을 지정합니다.

지정된 가로 세로 비율의 컨테이너는 가능한 한 많은 공간을 차지합니다. 모드에 따라 컨테이너는 사용 가능한 전체 영역(기본값), 너비 또는 높이를 차지하려고 합니다.

라이브러리에서 LayoutException 이 발생할 수 있습니다. 크기, 종횡비, 종횡비 모드 요구 사항을 충족하지 못하는 경우 발생합니다.

Unconstrained

컨테이너에는 크기 제한이 전혀 없습니다. 컨테이너에서 모든 크기 제약 조건을 제거하려면 Unconstrained 방법을 사용하세요.

제약이 없는 컨테이너의 콘텐츠는 콘텐츠의 고유 크기와 동일한 크기의 공간을 차지합니다. 제한되지 않은 컨테이너 자체는 공간을 차지하지 않습니다. 결과적으로 형제 컨테이너는 제한되지 않은 컨테이너의 콘텐츠를 덮을 수 있습니다.

PdfDocumentBuilder.Create().Generate("positioning-unconstrained.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().MinimalBox()
            .Border(b => b.Thickness(0.5))
            .Column(column =>
            {
                column.Item().Text("First item");

                column.Item().Unconstrained()
                    .Text("Second item ignores all size constraints");

                // 세 번째 항목에 빈 줄 사용
                column.Item().Text(new string(' ', 20))
                    .BackgroundColor(new PdfRgbColor(187, 237, 237), 50);

                column.Item().Text("Fourth item");
            });
    });
});

위 코드의 결과는 positioning-unconstrained.pdf 에 있습니다. 코드에서는 열의 세 번째 항목에 반투명 배경의 공백 줄을 사용했습니다. 보시다시피, 세 번째 항목은 두 번째(제약되지 않은) 항목을 부분적으로 덮습니다.

위치

컨테이너의 위치는 여러 가지에 따라 달라집니다. 그 중 일부는 정렬, 패딩, 상위 컨테이너의 위치 및 콘텐츠 방향입니다. 기본적으로 모든 컨테이너는 사용 가능한 가장 왼쪽 및 맨 위 위치에 고정됩니다.

Padding

가장 일반적인 요구 사항 중 하나는 컨테이너 콘텐츠 주위에 공간을 추가하는 것입니다. LayoutContainer 는 컨테이너의 패딩 영역을 설정하는 일련의 메소드를 제공합니다. 패딩 영역은 콘텐츠와 테두리 사이의 공간입니다. 다르게 말하면 패딩은 콘텐츠를 둘러싼 내부 공간을 나타냅니다.

Padding 방법은 컨테이너의 네 면 모두에 대한 패딩을 한 번에 설정합니다. 왼쪽과 오른쪽에만 패딩을 지정하려면 PaddingHorizontal 방법을 사용합니다. PaddingVertical 은 위쪽과 아래쪽에서만 동일한 작업을 수행합니다. 측면 패딩을 개별적으로 설정하려면 PaddingTop/Bottom/Left/Right 방법 중 하나를 사용하세요.

Align

컨테이너의 위치를 변경하려면 정렬 방법을 사용하세요. AlignLeft/AlignCenter/AlignRight 메소드는 수평 정렬을 적용하고 중첩된 컨테이너를 반환합니다. AlignTop/AlignMiddle/AlignBottom 메서드는 해당 수직 정렬이 포함된 중첩 컨테이너를 반환합니다.

명시적으로 적용된 정렬이 있는 컨테이너는 필요한 최소 너비 및/또는 높이의 영역을 차지합니다. 다음 코드는 두 개의 항목이 포함된 열을 만듭니다. 한 항목에 명시적으로 정렬이 적용되었습니다.

PdfDocumentBuilder.Create().Generate("positioning-alignment.pdf", doc =>
{
    var color = new PdfRgbColor(187, 237, 237);
    var text = "Hello";
    doc.Pages(page =>
    {
        page.Size(200, 100);
        page.Content().Column(c =>
        {
            c.Item().Extend().Background(color).Text(text);
            c.Item().Extend().AlignLeft().Background(color).Text(text);
        });
    });
});

Extend 호출은 두 항목이 전체 페이지를 차지하도록 만듭니다. 두 번째 항목에서 AlignLeft 메서드를 호출합니다. 항목의 컨테이너는 기본적으로 텍스트를 왼쪽으로 정렬하기 때문에 이 호출은 위치를 변경하지 않습니다. 그러나 명시적으로 적용된 정렬은 두 번째 항목이 차지하는 영역을 변경합니다.

위 코드의 결과는 positioning-alignment.pdf 에 있습니다.

Translate

컨테이너의 위치를 가로 및/또는 세로로 변경하려면 Translate/TranslateX/TranslateY 메서드를 사용하세요. 첫 번째는 컨테이너를 수평 및 수직으로 이동합니다. 나머지 두 개는 컨테이너를 한 방향으로만 이동합니다.

이러한 모든 방법은 위치를 재정의하지만 크기 제약 조건은 유지합니다. 이동된 컨테이너는 다른 컨테이너와 겹칠 수 있습니다. 왼쪽 및/또는 위로 이동하려면 음수 매개변수 값을 사용하십시오. 양수 값은 오른쪽 및/또는 아래쪽으로 이동합니다.

PdfDocumentBuilder.Create().Generate("positioning-translate.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(200, 100);
        page.Content().Row(r =>
        {
            r.ConstantItem(50)
                .Background(new PdfRgbColor(187, 237, 237))
                .Text("Left");

            r.ConstantItem(50)
                // 이 항목을 왼쪽으로 10포인트, 아래로 5포인트 이동
                .Translate(-10, 5)
                .Background(new PdfRgbColor(15, 130, 9))
                .Text("Right");
        });
    });
});

위 코드의 결과는 positioning-translate.pdf 에 있습니다.

Rotate

회전된 콘텐츠, 특히 텍스트는 다양한 방식으로 문서를 개선할 수 있습니다. 예를 들어, 공간을 절약하고 문서를 더욱 매력적이고 미적으로 보기 좋게 만들 수 있습니다.

LayoutContainer 는 콘텐츠를 회전하는 두 가지 접근 방식을 제공합니다. 어떤 접근 방식을 사용하든 회전된 콘텐츠가 포함된 컨테이너는 위치 및 크기 제약 조건을 따릅니다.

90도 회전

RotateRightRotateLeft 메서드는 콘텐츠를 각각 시계 방향과 시계 반대 방향으로 90도 회전합니다.

다음 코드는 기본 페이지 콘텐츠 옆에 세로 텍스트가 있는 문서를 만드는 방법을 보여줍니다.

PdfDocumentBuilder.Create().Generate("positioning-rotate.pdf", doc =>
{
    var lightGray = new PdfGrayColor(90);
    doc.Pages(page =>
    {
        page.Size(298, 210);
        page.Content().Row(r =>
        {
            r.AutoItem()
                .RotateLeft()
                .Background(lightGray)
                .Text("This content goes up");

            r.RelativeItem(1)
                .ExtendVertical()
                .PaddingHorizontal(10)
                .Column(t =>
                {
                    for (int i = 0; i < 15; i++)
                        t.Item().Text("The main content line goes here");
                });

            r.AutoItem()
                .RotateRight()
                .Background(lightGray)
                .Text("This content goes down");
        });
    });
});

위 코드의 결과는 positioning-rotate.pdf 에 있습니다.

어떤 각도로든 회전

Rotate 메서드는 임의의 각도만큼 콘텐츠를 회전합니다. 양수는 시계 방향으로 회전합니다. 음수는 반시계방향 회전을 의미합니다.

회전 원점은 컨테이너의 왼쪽 상단 모서리입니다. 회전된 콘텐츠는 다른 컨테이너와 겹칠 수 있습니다.

PdfDocumentBuilder.Create().Generate("positioning-rotate2.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(298, 210);
        page.Content()
            .Padding(25)
            .Background(new PdfGrayColor(70)) // 회색
            .AlignCenter()
            .AlignMiddle()

            .Background(new PdfGrayColor(100)) // 하얀색

            .Rotate(30)

            .Width(100)
            .Height(100)
            .Background(new PdfRgbColor(187, 237, 237)); // 파란색
    });
});

위 코드의 결과는 positioning-rotate2.pdf 에 있습니다.

회전 원점을 변경하려면 Rotate 호출 전에 Translate 메서드 중 하나를 호출하세요. 통화 후에는 원문을 다시 번역하는 것을 잊지 마세요.

// 회전 원점 이동
.TranslateX(50)
.TranslateY(50)

.Rotate(30)

// 다시 번역하다
.TranslateX(-50)
.TranslateY(-50)

조건부 레이아웃

PDF 문서의 레이아웃은 조건에 따라 달라질 수 있습니다. 예를 들어 열의 짝수 행과 홀수 행에 서로 다른 정렬이나 배경색을 사용할 수 있습니다.

조건에 따라 달라지는 레이아웃으로 중첩된 컨테이너를 삽입하려면 Container 메서드를 사용하세요. 이 메서드를 호출해도 호출 체인이 끊어지지 않습니다.

PdfDocumentBuilder.Create().Generate("positioning-container.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().Column(c =>
        {
            for (int i = 0; i < 15; i++)
            {
                c.Item()
                    .TextStyle(TextStyle.Parent.FontSize(14))
                    .Container(x => i % 2 == 0 ? x.Background(new PdfGrayColor(70)) : x)
                    .Text($"Row {i + 1}");
            }
        });
    });
});

위 코드의 결과는 positioning-container.pdf 에 있습니다.

DSL

문서의 일부 부분은 동일한 레이아웃을 사용할 수 있습니다. 예를 들어, 동일한 모양의 테두리를 설정하거나 동일한 서식을 사용할 수 있습니다. "반복하지 마세요" 원칙에 따라 공통 코드를 메소드로 추출하는 것이 좋습니다.

공통 코드에 대한 확장 방법을 사용하면 두 가지 이점이 있습니다.

  • 메소드 호출 체인에서 메소드를 사용할 수 있습니다.
  • 일련의 메소드 호출에 대해 의미 있는 이름을 가질 수 있습니다.

이러한 이점을 바탕으로 DSL(도메인별 언어)을 구성할 수 있습니다. DSL을 사용하면 레이아웃 코드가 더 짧아지고 이해하기 쉬워집니다.

static class LayoutHelpers
{
    public static LayoutContainer NumberCell(this Table table)
        => table.Cell().Border(b => b.Thickness(0.5)).PaddingHorizontal(10);
}

PdfDocumentBuilder.Create().Generate("positioning-dsl.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.NumberCell().Text($"{i + 1}");
    });
}));

렌더링 과정

Layout 추가 기능은 크기 및 위치 제약에 따라 컨테이너에 넣은 모든 콘텐츠를 정렬합니다. 일부 콘텐츠는 여러 페이지에 걸쳐 있을 수 있습니다. 콘텐츠가 렌더링되는 엄격한 순서가 있습니다. 콘텐츠 흐름은 이 주문의 또 다른 이름입니다.

LayoutContainer 는 콘텐츠 흐름을 조정하기 위한 몇 가지 방법을 제공합니다. 매번 필요하지 않을 수도 있지만 필요한 레이아웃을 달성하는 다른 방법이 없는 경우가 있습니다.

PageBreak

새 페이지에서 콘텐츠 블록을 시작해야 하는 경우 PageBreak 메서드를 사용하세요. 예를 들어, 이 메서드를 사용하여 새 페이지에서 Column 항목을 시작할 수 있습니다.

다음은 각 페이지에 두 개의 행만 포함되도록 열을 나누는 샘플 코드입니다.

PdfDocumentBuilder.Create().Generate("positioning-pagebreak.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Column(c =>
    {
        for (int i = 1; i <= 10; ++i)
        {
            c.Item().Text($"Item {i}");

            if (i % 2 == 0)
                c.Item().PageBreak();
        }
    });
}));

위 코드의 결과는 positioning-pagebreak.pdf 에 있습니다.

ShowIf

조건에 따라 컨테이너를 표시하거나 숨겨야 할 수도 있습니다. 이 특수한 조건부 레이아웃 사례에 대한 기본 구문을 제공하는 ShowIf 메서드가 있습니다.

다음 코드에서는 ShowIf 메서드를 사용하여 행의 각 5개 요소 뒤에 수직선을 삽입합니다.

PdfDocumentBuilder.Create().Generate("positioning-showif.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Row(r =>
    {
        for (int i = 0; i < 10; ++i)
        {
            r.AutoItem().Text(i.ToString());
            r.AutoItem().ShowIf(i > 0 && (i + 1) % 5 == 0).LineVertical(0.5);
        }
    });
}));

위 코드의 결과는 positioning-showif.pdf 에 있습니다.

ShowOnce

다음 페이지에서 내용이 반복되는 것을 방지할 수 있습니다. 레이아웃 엔진에 콘텐츠를 한 번만 완전히 렌더링하도록 지시하려면 ShowOnce 메서드를 사용하세요.

다음 코드를 확인하여 ShowOnce 가 어떻게 두 번째 페이지에 "Environment" 가 표시되지 않는지 확인하세요.

PdfDocumentBuilder.Create().Generate("positioning-showonce.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Row(r =>
    {
        r.RelativeItem()
            .Background(new PdfGrayColor(75))
            .Border(b => b.Thickness(0.5))
            .Padding(5)
            .ShowOnce()
            .Text("Environment");

        r.RelativeItem()
            .Border(b => b.Thickness(0.5))
            .Padding(5)
            .Column(c =>
            {
                c.Item().Text(Environment.OSVersion.VersionString);
                c.Item().Text(string.Empty);
                c.Item().Text(
                    Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")
                    ?? string.Empty
                );
            });
    });
}));

위 코드의 결과는 positioning-showonce.pdf 에 있습니다.

ShowEntire

기본 동작은 콘텐츠가 한 페이지에 맞지 않을 때 페이지 간에 콘텐츠를 분할하는 것입니다. 전체 컨테이너를 한 페이지에 렌더링하려면 ShowEntire 메서드를 사용하세요.

전체 내용을 한 페이지에 담을 수 없는 경우 라이브러리에서 LayoutException 이 발생합니다.

다음 코드의 ShowEntire 호출로 인해 두 번째 항목 텍스트가 두 번째 페이지부터 시작됩니다. 호출이 없으면 첫 번째 항목 텍스트 바로 다음의 첫 번째 페이지에서 시작됩니다.

PdfDocumentBuilder.Create().Generate("positioning-showentire.pdf", doc => doc.Pages(page =>
{
    page.Size(100, 100);
    page.Content().Column(c =>
    {
        c.Item().Text(t =>
        {
            for (var i = 0; i < 4; i++)
                t.Line($"First item line {i + 1}");
        });

        c.Item()
            .Background(new PdfRgbColor(250, 123, 5))
            .ShowEntire()
            .Text(t =>
            {
                for (var i = 0; i < 4; i++)
                    t.Line($"Second item line {i + 1}");
            });
    });
}));

위 코드의 결과는 positioning-showentire.pdf 에 있습니다.

EnsureSpace

어떤 의미에서 EnsureSpaceShowEntire 메서드의 특별한 경우입니다. 차이점은 EnsureSpace 는 전체 콘텐츠가 페이지에 맞도록 요구하지 않는다는 것입니다. 이 메서드는 지정된 높이에 콘텐츠의 일부만 맞추려고 시도합니다. 다른 모든 내용은 다음 페이지에서 진행됩니다.

현재 페이지의 비어 있는 영역의 높이가 요청한 것보다 작은 경우 전체 콘텐츠가 새 페이지에 렌더링됩니다. 여기서 이 메소드는 ShowEntire 메소드와 동일한 결과를 생성합니다.

StopPaging

최대 한 페이지에 출력을 생성하려면 StopPaging 메서드를 사용하세요. 컨테이너에서 이 메서드를 호출하면 페이징이 방지됩니다. Layout 추가 기능은 이 컨테이너의 콘텐츠를 페이지 간에 분할하지 않습니다. 한 페이지에 맞지 않는 데이터는 렌더링하지 않습니다.

다음 샘플 코드는 문서에 두 페이지 세트를 추가합니다. 두 세트 모두 요일 이름 목록을 콘텐츠로 사용합니다. 코드가 페이지의 콘텐츠 컨테이너에 대해 StopPaging 메서드를 호출하기 때문에 첫 번째 세트에는 하나의 페이지만 있습니다.

PdfDocumentBuilder.Create().Generate("positioning-stoppaging.pdf", doc =>
{
    static Action<TextContainer> produceText(string heading)
    {
        var text = string.Join('\n', DateTimeFormatInfo.InvariantInfo.DayNames);
        return t =>
        {
            t.Line(heading).BackgroundColor(new PdfRgbColor(250, 123, 5));
            t.Span(text);
        };
    }

    doc.Pages(page =>
    {
        page.Size(100, 100);
        page.Content()
            .StopPaging()
            .Text(produceText("Without paging:"));
    });

    doc.Pages(page =>
    {
        page.Size(100, 100);
        page.Content()
            .Text(produceText("Default behaviour:"));
    });
});

위 코드의 결과는 positioning-stoppaging.pdf 에 있습니다.

SkipOnce

콘텐츠 표시를 연기할 수 있습니다. 컨테이너가 두 페이지 이상에 나타나는 경우 SkipOnce 를 사용하여 첫 번째 페이지를 건너뛰고 두 번째 페이지부터 모든 페이지의 콘텐츠를 렌더링합니다.

이 기능은 모든 종류의 헤더에 유용하지만 다른 콘텐츠에도 사용할 수 있습니다. 다음 코드를 확인하여 SkipOnce가 헤더가 첫 페이지에 표시되는 것을 방지하는 방법을 확인하세요.

PdfDocumentBuilder.Create().Generate("positioning-skiponce.pdf", doc => doc.Pages(page =>
{
    page.Size(298, 210);

    page.Header()
        .SkipOnce()
        .Text("This header will appear starting from page 2")
        .Style(TextStyle.Parent.Underline());

    page.Content().Column(c =>
    {
        for (int i = 0; i < 5; i++)
        {
            if (i > 0)
                c.Item().PageBreak();

            c.Item().Text($"Page {i + 1}");
        }
    });
}));

위 코드의 결과는 positioning-skiponce.pdf 에 있습니다.

콘텐츠 방향

기본 콘텐츠 방향은 왼쪽에서 오른쪽입니다. 컨테이너는 텍스트와 기타 콘텐츠를 왼쪽에 정렬합니다.

그러나 오른쪽에서 왼쪽으로 쓰는 언어도 있습니다(예: 아랍어, 히브리어). 이러한 언어로 콘텐츠를 만들 때는 ContentFromRightToLeft 메서드를 사용하세요. 이를 호출하면 컨테이너의 콘텐츠 방향이 오른쪽에서 왼쪽으로 전환됩니다. 이 메서드는 기본 정렬도 전환합니다.

페이지의 콘텐츠 대부분이 RTL 언어로 되어 있는 경우 오른쪽에서 왼쪽을 페이지의 기본 콘텐츠 방향으로 설정할 수 있습니다. 이를 위해 PageLayout.ContentFromRightToLeft 메소드를 사용하세요. 그런 다음 선택한 컨테이너의 기본 콘텐츠 방향을 재정의하려면 ContentFromLeftToRight 메서드를 사용하세요.

콘텐츠 방향은 명시적으로 지정된 정렬에 영향을 주지 않습니다. 예를 들어 오른쪽 정렬된 콘텐츠는 컨테이너에 어떤 콘텐츠 방향을 설정하더라도 오른쪽에 고정됩니다. 자식 요소의 시각적 순서는 콘텐츠의 방향에 따라 달라집니다.