QuestPDF 页面
这个容器包含多个与页面相关的插槽。
主插槽
主插槽(Header
、Content
和 Footer
)可用于指定页面内容:
Header
元素始终位于每个页面的顶部。Content
元素绘制在Header
和Footer
之间的空间中。Footer
元素始终位于每个页面的底部。
.Page(page =>
{
page.MarginHorizontal(40);
page.MarginVertical(60);
page.Header()
.Height(60)
.Background(Colors.Grey.Lighten1)
.AlignCenter()
.AlignMiddle()
.Text("Header");
page.Content()
.Background(Colors.Grey.Lighten2)
.AlignCenter()
.AlignMiddle()
.Text("Content");
page.Footer()
.Height(30)
.Background(Colors.Grey.Lighten1)
.AlignCenter()
.AlignMiddle()
.Text("Footer");
});
请注意!当头部和底部元素的高度之和大于页面总高度时,没有足够的空间容纳内容,此时会抛出布局异常。
水印插槽
水印插槽(背景和前景)可用于分别在主要内容背后或前方添加内容。
.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(1, Unit.Inch);
page.DefaultTextStyle(TextStyle.Default.FontSize(16));
page.PageColor(Colors.White);
const string transparentBlue = "#662196f3";
page.Background()
.AlignTop()
.ExtendHorizontal()
.Height(200)
.Background(transparentBlue);
page.Foreground()
.AlignBottom()
.ExtendHorizontal()
.Height(250)
.Background(transparentBlue);
page.Header()
.Text("Background and foreground")
.Bold().FontColor(Colors.Blue.Darken2).FontSize(36);
page.Content().PaddingVertical(25).Column(column =>
{
column.Spacing(25);
foreach (var i in Enumerable.Range(0, 100))
column.Item().Background(Colors.Grey.Lighten2).Height(75);
});
});
考虑一个更复杂的例子,它在实际内容旁边添加额外的视觉元素。这可以通过水印插槽轻松实现:
document.Page(page =>
{
const float horizontalMargin = 1.5f;
const float verticalMargin = 1f;
page.Size(PageSizes.A4);
page.MarginVertical(verticalMargin, Unit.Inch);
page.MarginHorizontal(horizontalMargin, Unit.Inch);
page.Background()
.PaddingVertical(verticalMargin, Unit.Inch)
.RotateRight()
.Decoration(decoration =>
{
decoration.Before().RotateRight().RotateRight().Element(DrawSide);
decoration.Content().Extend();
decoration.After().Element(DrawSide);
void DrawSide(IContainer container)
{
container
.Height(horizontalMargin, Unit.Inch)
.AlignMiddle()
.Row(row =>
{
row.AutoItem().PaddingRight(16).Text("COMPANY NAME").FontSize(16).FontColor(Colors.Red.Medium);
row.RelativeItem().PaddingTop(12).ExtendHorizontal().LineHorizontal(2).LineColor(Colors.Red.Medium);
});
}
});
page.Content().Column(column =>
{
column.Spacing(25);
foreach (var i in Enumerable.Range(1, 100))
column.Item().Background(Colors.Grey.Lighten2).Height(75).AlignCenter().AlignMiddle().Text(i.ToString()).FontSize(16);
});
});
这将产生以下结果:
页面设置
可以创建一个文档,其中包含具有不同设置的页面。例如,以下代码插入一张 A4 页面,然后是一张 A3 页面,两者具有不同的边距:
public class StandardReport : IDocument
{
// 元数据
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.MarginVertical(80);
page.MarginHorizontal(100);
page.PageColor(Colors.Grey.Medium); // 透明是默认值
page.Size(PageSizes.A3);
page.Header().Element(ComposeHeader);
page.Content().Element(ComposeBigContent);
page.Footer().AlignCenter().PageNumber();
})
.Page(page =>
{
// 您可以在文档中指定多个页面类型,具有独立配置
page.Margin(50)
page.Size(PageSizes.A4);
page.Header().Element(ComposeHeader);
page.Content().Element(ComposeSmallContent);
page.Footer().AlignCenter().PageNumber();
});
}
// 内容实现
}
您很容易更改页面方向,如下所示:
// 默认为纵向
page.Size(PageSizes.A3);
// 显式纵向方向
page.Size(PageSizes.A3.Portrait());
// 改为横向方向
page.Size(PageSizes.A3.Landscape());
连续页面大小
可以定义具有已知宽度但动态高度的页面大小。在下面的示例中,生成的页面具有恒定宽度(等于 A4 页面的宽度,但其高度取决于内容:
public class StandardReport : IDocument
{
// 元数据
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.MarginVertical(40);
page.MarginHorizontal(60);
page.ContinuousSize(PageSizes.A4.Width);
page.Header().Element(ComposeHeader);
page.Content().Element(ComposeContent);
page.Footer().AlignCenter().PageNumber();
});
}
// 内容实现
}
由于实际布局限制,最大页面高度限制为 14400 点(约 5 米)。
全局文本样式
QuestPDF 库提供了一组默认样式,用于应用于文本。
.Text("使用库默认样式的文本")
您可以通过提供附加参数来调整文本样式:
.Text("红色粗体大小为 20 的文本").FontSize(20).SemiBold()
上述选项覆盖了默认样式。为了获得更多控制,您可以在文档中设置默认文本样式。请注意,所有更改都是累积的,如以下示例所示:
public class SampleReport : IDocument
{
public DocumentMetadata GetMetadata() => new DocumentMetadata();
public void Compose(IDocumentContainer container)
{
container.Page(page =>
{
// 在这一系列页面中,所有文本的大小为 20
page.DefaultTextStyle(TextStyle.Default.FontSize(20));
page.Margin(20);
page.Size(PageSizes.A4);
page.PageColor(Colors.White);
page.Content().Column(column =>
{
column.Item().Text(Placeholders.Sentence());
column.Item().Text(text =>
{
// 文本块内的文本此外还加粗
text.DefaultTextStyle(x => x.SemiBold());
text.Line(Placeholders.Sentence());
// 此文本的大小为 20,但也有粗体和红色
text.Span(Placeholders.Sentence()).FontColor(Colors.Red.Medium);
});
});
});
}
}
全局内容方向(从右到左)
可以全局指定整个文档的内容方向。
提示: 要了解更多关于内容方向的工作原理,请阅读有关ContentDirection元素的文档。
document.Page(page =>
{
// 默认设置
page.ContentFromLeftToRight();
// 可选的从右到左模式
page.ContentFromRightToLeft();
});
进一步的示例如下:
document.Page(page =>
{
page.Size(PageSizes.A5);
page.Margin(20);
page.PageColor(Colors.White);
page.DefaultTextStyle(x => x.FontFamily("Calibri").FontSize(20));
page.ContentFromRightToLeft();
page.Content().Column(column =>
{
column.Spacing(20);
column.Item()
.Text("مثال على الفاتورة") // example invoice
.FontSize(32).FontColor(Colors.Blue.Darken2).SemiBold();
column.Item().Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.ConstantColumn(75);
columns.ConstantColumn(100);
});
table.Cell().Element(HeaderStyle).Text("وصف السلعة"); // item description
table.Cell().Element(HeaderStyle).Text("كمية"); // quantity
table.Cell().Element(HeaderStyle).Text("سعر"); // price
var items = new[]
{
"دورة البرمجة", // programming course
"دورة تصميم الرسومات", // graphics design course
"تحليل وتصميم الخوارزميات", // analysis and design of algorithms
};
foreach (var item in items)
{
var price = Placeholders.Random.NextDouble() * 100;
table.Cell().Text(item);
table.Cell().Text(Placeholders.Random.Next(1, 10));
table.Cell().Text($"USD${price:F2}");
}
static IContainer HeaderStyle(IContainer x) => x.BorderBottom(1).PaddingVertical(5);
});
});
});