Welcome GuestLogin

PDFsharp and MigraDoc Wiki

RSS RSS

Navigation




Quick Search
»

PoweredBy

Visit the new Website for PDFsharp & MigraDoc Foundation 6.0 for .NET 6 and find information about the new version for Windows, Linux, and other platforms.

<< Previous^UpNext >>
This sample shows one way to create a PDF document with multiple pages.

Do we need such a sample?

Not really.

When you program reaches the end of a page, you just have to create a new page by calling the "AddPage()" method of the PdfDocument class. Then you create a new XGraphics object for the new page and use it to draw on the second page, beginning at the top.

Experience shows that users sometimes have difficulties to modify there code with support for a second page. They call "AddPage()", but do not store the return value. They do not create a new XGraphics object and continue to draw on the first page. Or they try to create a new XGraphics object, but pass the first page as a parameter and receive an error message.

If you know right from the start that you will or may need more than one page, then take this into account right from the start and your program will be readable and easy to maintain.

Note:  Consider using MigraDoc instead of PDFsharp for large documents. You can use many attributes to format text and you get the linebreaks and pagebreaks for free.

PDF Output File

We do not have sample output yet.

Screen Shots

We do not have screen shots yet.

Source Code

The class LayoutHelper takes care of the line position and creates pages as needed:
public class LayoutHelper
{
    private readonly PdfDocument _document;
    private readonly XUnit _topPosition;
    private readonly XUnit _bottomMargin;
    private XUnit _currentPosition;
 
    public LayoutHelper(PdfDocument document, XUnit topPosition, XUnit bottomMargin)
    {
        _document = document;
        _topPosition = topPosition;
        _bottomMargin = bottomMargin;
        // Set a value outside the page - a new page will be created on the first request.
        _currentPosition = bottomMargin + 10000;
    }
 
    public XUnit GetLinePosition(XUnit requestedHeight)
    {
        return GetLinePosition(requestedHeight, -1f);
    }
 
    public XUnit GetLinePosition(XUnit requestedHeight, XUnit requiredHeight)
    {
        XUnit required = requiredHeight == -1f ? requestedHeight : requiredHeight;
        if (_currentPosition + required > _bottomMargin)
            CreatePage();
        XUnit result = _currentPosition;
        _currentPosition += requestedHeight;
        return result;
    }
 
    public XGraphics Gfx { get; private set; }
    public PdfPage Page { get; private set; }
 
    void CreatePage()
    {
        Page = _document.AddPage();
        Page.Size = PageSize.A4;
        Gfx = XGraphics.FromPdfPage(Page);
        _currentPosition = _topPosition;
    }
}

And sample code that shows the LayoutHelper class at work. The sample uses short texts that will always fit into a single line. Adding linebreaks to texts that do not fit into a single line is beyond the scope of this sample.

I wrote it before: Consider using MigraDoc instead of PDFsharp for large documents. You can use many attributes to format text and you get the linebreaks and pagebreaks for free.
PdfDocument document = new PdfDocument();
 
// Sample uses DIN A4, page height is 29.7 cm. We use margins of 2.5 cm.
LayoutHelper helper = new LayoutHelper(document, XUnit.FromCentimeter(2.5), XUnit.FromCentimeter(29.7 - 2.5));
XUnit left = XUnit.FromCentimeter(2.5);
 
// Random generator with seed value, so created document will always be the same.
Random rand = new Random(42);
 
const int headerFontSize = 20;
const int normalFontSize = 10;
 
XFont fontHeader = new XFont("Verdana", headerFontSize, XFontStyle.BoldItalic);
XFont fontNormal = new XFont("Verdana", normalFontSize, XFontStyle.Regular); 
 
const int totalLines = 666;
bool washeader = false;
for (int line = 0; line < totalLines; ++line)
{
    bool isHeader = line == 0 || !washeader && line < totalLines - 1 && rand.Next(15) == 0;
    washeader = isHeader;
    // We do not want a single header at the bottom of the page, so if we have a header we require space for header and a normal text line.
    XUnit top = helper.GetLinePosition(isHeader ? headerFontSize + 5: normalFontSize + 2, isHeader ? headerFontSize + 5 + normalFontSize : normalFontSize);
 
    helper.Gfx.DrawString(isHeader ? "Sed massa libero, semper a nisi nec" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
        isHeader ? fontHeader : fontNormal, XBrushes.Black, left, top, XStringFormats.TopLeft);
}
 
// Save the document... 
const string filename = "MultiplePages.pdf";
document.Save(filename);
// ...and start a viewer.
Process.Start(filename); 

Note: The samples on this site usually show and discuss code snippets only. The complete source code of the samples with solutions for Visual Studio is available from the download area on CodePlex.


Visit the new Website for PDFsharp & MigraDoc Foundation 6.0 for .NET 6 and find information about the new version for Windows, Linux, and other platforms.



Miscellaneous
Home
PDFsharp
FAQ
Samples
Articles
MigraDoc
FAQ
Samples
Articles

ScrewTurn Wiki version 3.0.5.600. Some of the icons created by FamFamFam.

Impressum - Privacy Policy, Data Protection Declaration, Legal Notice