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

컨테이너와 그 내용물

문서는 페이지들의 집합입니다. 각 페이지는 다시 콘텐츠 조각들의 집합입니다. 이미 알고 계실 수도 있지만, PageLayout 클래스는 मुख्य 콘텐츠와 추가 콘텐츠를 위한 컨테이너를 제공합니다. 하지만 이 컨테이너들을 어떻게 사용해야 할까요?

페이지 콘텐츠용 컨테이너

컨테이너는 페이지의 콘텐츠를 구성하는 데 도움이 됩니다. 페이지에 넣는 모든 것은 반드시 컨테이너 안에 들어가야 합니다. 콘텐츠가 충분히 크면 하나의 컨테이너가 한 페이지를 넘어 여러 페이지에 걸쳐 공간을 차지할 수 있습니다.

컨테이너에는 텍스트나 이미지를 넣을 수 있습니다. 정렬 및 위치 지정 목적상 한 컨테이너 안에 다른 컨테이너를 넣을 수도 있습니다. 하나 이상의 콘텐츠 조각을 담을 수 있는 컨테이너도 있습니다.

페이지의 컨테이너는 LayoutContainer 클래스의 객체로 표현됩니다. 이 클래스를 사용해 컨테이너의 크기, 위치, 콘텐츠 및 렌더링 과정을 설정합니다.

이 문서는 PDF 생성용 Layout API 시리즈의 일부입니다. API가 처음이라면 먼저 Layout API 시작하기 부분을 읽어 보세요.

컨테이너 작동 방식

컨테이너를 얻는 것으로 시작합니다. 예를 들어 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는 dash patterns을 사용하는 선을 지원합니다.

위 코드의 결과는 containers-decor.pdf에서 확인할 수 있습니다.

콘텐츠

LayoutContainer 클래스가 콘텐츠 구성에 무엇을 제공하는지 살펴보겠습니다.

Text

컨테이너에 텍스트를 추가하려면 Text 메서드 중 하나를 사용합니다.

모든 텍스트가 같은 스타일을 사용한다면 메서드의 간단한 단축 버전을 사용합니다. 이 버전은 문자열을 받아 TextSpan 객체를 반환합니다. 이 객체를 사용해 해당 span의 텍스트 스타일을 설정할 수 있습니다.

Text 메서드에는 Action<TextContainer> 형식의 대리자를 받는 또 다른 버전이 있습니다. 하나의 텍스트 블록 안에 서로 다른 스타일의 span을 넣으려면 이 버전을 사용합니다. TextContainer는 텍스트 span 사이에 이미지와 다른 요소를 삽입하는 메서드를 제공합니다. 문단 간 간격을 설정할 수 있는 기능 같은 다른 고급 기능도 있습니다.

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

Layout API는 파일이나 스트림의 이미지 데이터로부터 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 컨테이너는 무제한 개수의 항목을 가로로 구성하는 데 도움이 됩니다. 행의 각 항목은 컨테이너입니다. 따라서 서로 다른 유형의 콘텐츠를 행에 넣을 수 있습니다.

var rowItems = new[] { "three", "two", "one" };

PdfDocumentBuilder.Create().Generate("containers-row.pdf", doc => doc.Pages(page =>
{
    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 컨테이너의 모든 기능은 표 컨테이너 문서에서 확인할 수 있습니다.

Inlined

InlineContainer 컨테이너 유형은 컨테이너 컬렉션의 항목으로 영역을 채우는 편리한 방법을 제공합니다. 항목을 하나씩 차례대로 추가하면 라이브러리가 그것들을 한 줄에 하나씩 배치합니다. 항목을 배치할 공간이 없으면 라이브러리는 새 줄을 시작합니다.

InlineContainer 컨테이너에 대한 자세한 내용은 복합 컨테이너 문서에 있습니다.

Layers

여러 레이어에 콘텐츠를 배치하는 것이 가장 좋은 경우가 있습니다. LayerContainer 컨테이너 유형은 바로 이 목적을 위해 존재합니다. 정확히 하나의 주 레이어와 원하는 수의 비주 레이어를 정의해야 합니다. Layout API는 생성한 순서와 동일한 순서로 레이어를 합성합니다.

LayerContainer 유형에 대한 자세한 내용은 복합 컨테이너를 읽어 보세요.

Element

이것은 특별한 종류의 콘텐츠입니다. 요소를 동적으로 생성하고 그 결과를 컨테이너에 넣을 수 있습니다.

동적으로 생성된 요소는 페이지 번호, 크기 및 기타 속성에 따라 달라지는 레이아웃을 제공할 수 있습니다.