該頁面可以包含自動翻譯的文字。
容器及其內容
文件是由一組頁面構成的。每個頁面又是由一組內容片段構成的。您可能已經知道,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 物件。您可以使用該物件來設定該區段的文字樣式。
Text 方法還有另一個版本,接受類型為 Action<TextContainer> 的委派。使用該版本可在同一段文字中包含不同樣式的區段。TextContainer 提供方法,可在文字區段之間插入圖片與其他元素。還有其他進階功能,例如設定段落間距。
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
這是一種特殊的內容。您可以動態建立元素,並將結果放入容器中。
動態建立的元素可以提供依賴頁碼、大小及其他屬性的版面配置。