이 페이지에는 자동 번역된 텍스트가 포함될 수 있습니다.
컨테이너의 크기, 위치 및 렌더링
문서에서 가장 중요한 부분은 콘텐츠입니다. 이는 의심의 여지가 없습니다. 또 다른 중요한 부분은 명확하고 전문적이며 효과적인 커뮤니케이션을 만드는 서식입니다. 올바르게 서식이 지정된 문서는 시각적으로 매력적이고, 읽기 쉬우며, 탐색하기도 쉽습니다.
이미 컨테이너를 사용하여 콘텐츠를 구성하는 방법을 알고 있을 수 있습니다. 그리고 배경색을 적용하는 방법도 알고 있을 수 있습니다. 이 문서에서는 컨테이너의 크기와 위치를 지정하는 방법을 설명합니다. 또한 조건부 콘텐츠 렌더링 같은 고급 기능도 다룹니다. 오른쪽에서 왼쪽 콘텐츠 방향 지원에 대한 정보도 포함되어 있습니다.

LayoutContainer 클래스는 컨테이너를 전문적으로 배치하는 데 필요한 모든 기능을 제공합니다. 패딩과 정렬을 적용하면 사용자에게 좋은 인상을 남기는 문서를 만들 수 있습니다.
이 문서는 PDF 생성을 위한 Layout API 시리즈의 일부입니다. API를 처음 사용한다면 먼저 Layout API 시작하기 부분을 읽어 보세요.
크기
기본적으로 컨테이너는 콘텐츠에 필요한 가장 작은 영역을 차지합니다. 다시 말해, 컨테이너의 크기는 콘텐츠의 고유 크기와 같습니다.
이미지의 고유 크기는 이미지 파일 자체의 차원으로 결정됩니다. 텍스트 스팬의 고유 크기는 스팬의 모든 글리프를 포함하는 영역의 크기입니다.
Column 또는 Table 같은 복합 컨테이너의 크기는 컨테이너 구성 요소의 크기에 따라 달라집니다.
Width & Height
Width 및 Height 메서드를 사용하여 컨테이너의 정확한 너비와 높이를 지정할 수 있습니다. 이는 자리 표시자 컨테이너에 매우 편리합니다.
정확한 크기는 이미지에도 잘 맞습니다. Layout API가 ImageContentMode에 따라 이미지를 컨테이너에 맞게 축소하거나 채우기 때문입니다.
복합 컨테이너와 텍스트가 있는 컨테이너에 정확한 크기를 사용할 때는 주의해야 합니다. 제공된 크기에 콘텐츠를 맞출 수 없으면 LayoutException이 발생합니다.
너비 또는 높이에만 제약을 두고 싶을 때가 있습니다. MinWidth, MinHeight, MaxWidth, MaxHeight 메서드를 사용하여 제약을 설정할 수 있습니다.
제약 조건을 만족할 수 없으면 라이브러리가 LayoutException을 throw한다는 점에 유의하세요.
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
LayoutContainer 클래스는 MinimalBox 메서드를 제공합니다. 이는 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을 throw할 수 있다는 점에 유의하세요. 이는 크기, 종횡비, 종횡비 모드 요구 사항을 충족할 수 없을 때 발생합니다.
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)
// 이 항목을 왼쪽으로 10pt, 아래로 5pt 이동
.Translate(-10, 5)
.Background(new PdfRgbColor(15, 130, 9))
.Text("Right");
});
});
});
위 코드의 결과는 positioning-translate.pdf에 있습니다.
Rotate
회전된 콘텐츠, 특히 텍스트는 여러 방식으로 문서를 개선할 수 있습니다. 예를 들어 공간을 절약하고 문서를 더 흥미롭고 미적으로 더 보기 좋게 만들 수 있습니다.
LayoutContainer 클래스는 콘텐츠를 회전하는 두 가지 방법을 제공합니다. 어떤 방법을 사용하든 회전된 콘텐츠가 있는 컨테이너는 위치와 크기 제약을 준수합니다.
90도 회전
RotateRight 및 RotateLeft 메서드는 콘텐츠를 시계 방향과 반시계 방향으로 각각 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)) // gray
.AlignCenter()
.AlignMiddle()
.Background(new PdfGrayColor(100)) // white
.Rotate(30)
.Width(100)
.Height(100)
.Background(new PdfRgbColor(187, 237, 237)); // blue
});
});
위 코드의 결과는 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을 throw한다는 점에 유의하세요.
다음 코드의 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
어느 의미에서 EnsureSpace는 ShowEntire 메서드의 특수한 경우입니다. 차이점은 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 메서드를 사용합니다.
콘텐츠 방향은 명시적으로 지정된 정렬에는 영향을 주지 않는다는 점에 유의하세요. 예를 들어, 오른쪽 정렬된 콘텐츠는 컨테이너에 어떤 콘텐츠 방향을 설정하든 항상 오른쪽에 붙습니다. 자식 요소의 시각적 순서는 콘텐츠 방향에 따라 달라집니다.