PdfDocument Class
The main class of the DevExpress PDF Document API library. Contains the document model and key PDF processing APIs.
Namespace: DevExpress.Docs.Pdf
Assembly: DevExpress.Docs.Pdf.v26.1.dll
Declaration
Remarks
Use the new PdfDocument class to access the document model and key PDF processing APIs:
- PdfDocument.Pages — a mutable Page object collection
- Page.Fragments — a FragmentCollection that exposes all visual page content
- Page.Annotations — a strongly typed annotation collection
- PdfDocument.Fields — a FormFieldCollection for interactive forms
- PdfDocument.Metadata — document info and structured XMP metadata
- PdfDocument.StructureTree — the logical structure tree used for tagged PDFs
- PdfDocument.Attachments — embedded file collection
- PdfDocument.Encrypt / PdfDocument.RemoveEncryption — document security management
- PdfDocument.AppendDocument — document composition and merging
Get Started
Run the following console command to install the DevExpress.Docs.Pdf NuGet package:
dotnet add package DevExpress.Docs.Pdf
Use this package to work with PDF documents. The following code snippet creates a new PDF document:
using DevExpress.Docs.Pdf;
using var document = new PdfDocument();
// Create and add a page
Page page = new Page();
document.Pages.Add(page);
// Add text content
page.AddTextFragment("Hello PDF", 72, 720);
// Save document
using (var stream = new FileStream("output.pdf", FileMode.Create))
{
document.Save(stream);
}
Merge Documents
The DevExpress PDF API allows you to copy individual pages between documents and append entire PDF files. All pages, annotations, form fields, and metadata are preserved.
Use the PdfDocument.AppendDocument method to append a PDF file to the end of the current document:
Organize Pages
Use the PdfDocument.Pages property to access the PageCollection object.
The PDF Document API library supports the following page management actions:
- Add new pages to a PDF document
- Copy and reorder pages within a PDF document
- Copy pages from one PDF document to another
- Rotate and resize pages
- Rotate, scale, and offset page content
- Remove pages from a PDF document
The following code snippet adds pages to a PDF document: one page at the end of the document and another page after the first page.
using DevExpress.Docs.Pdf;
using DevExpress.Drawing.Printing;
using System.IO;
using (PdfDocument pdfDocument = new PdfDocument(
new FileStream(@"C:\Test Documents\Document.pdf", FileMode.Open,
FileAccess.ReadWrite)))
{
// Add pages to the end and at a specific position.
pdfDocument.Pages.Add(DXPaperKind.A4);
pdfDocument.Pages.Insert(1, new Page(DXPaperKind.Letter));
pdfDocument.Save(new FileStream(@"C:\Test Documents\Document_upd.pdf",
FileMode.Create, FileAccess.Write));
}
Add Content to Pages
To add content to a PDF document, first create a content fragment: text, image, shape, or form. Add the object to the FragmentCollection available via the Fragments property.
The following code snippet creates a paragraph and adds it to a PDF page:

using DevExpress.Docs.Pdf;
using DevExpress.Drawing;
using DevExpress.Drawing.Printing;
using System.Drawing;
using System.IO;
using (PdfDocument pdfDocument = new PdfDocument()) {
var page = pdfDocument.Pages.Add(DXPaperKind.A4);
// Create a paragraph fragment.
var multiLine = new ParagraphFragment(){
Text = "The PDF Document API is a non-visual .NET library that allows you to " +
"generate, convert, merge, split, edit, password-protect, and digitally " +
"sign PDF files.",
Location = new PointF(10, 740),
Font = new DXFont("Courier New", 11, DXFontStyle.Regular),
Width = 500,
Height = 500,
StringFormat = new DXStringFormat() {
Alignment = DXStringAlignment.Center,
LineAlignment = DXStringAlignment.Near,
},
};
// Add the paragraph to the PDF page.
page.AddFragment(multiLine);
pdfDocument.Save(new FileStream("Result.pdf", FileMode.Create, FileAccess.Write));
}
Generate Tagged PDFs
The DevExpress PDF API exposes the logical structure of a PDF document through PdfDocument.StructureTree allowing you to build, inspect, and validate tagged PDFs.
Use the Structure Tree API to generate fully tagged PDFs, ensure compliance with PDF/UA standards, and integrate accessibility into automated document generation pipelines. You can also enhance or repair structure in existing documents.
The structure model is based on a hierarchical StructureElement tree with support for PDF 1.7 and PDF 2.0 structure types.
The PdfDocument.StructureTree property returns the structure tree of a PDF document. Each node of the structure tree is a StructureElement object. Call the StructureTree.AddChildElement(StructureTypeDescriptor) method to add a child element to the structure tree.
The following code snippet creates a new tagged PDF document.
using DevExpress.Docs.Pdf;
using DevExpress.Drawing.Printing;
using System.Drawing;
using System.IO;
using (PdfDocument document = new PdfDocument())
{
Page page = document.Pages.Add(DXPaperKind.A4);
// Create the root Document element.
StructureElement doc = document.StructureTree
.AddChildElement(Pdf17StructureType.Document);
// Add a section to the document.
StructureElement section =
doc.AddChildElement(Pdf17StructureType.Sect);
// Add a heading.
StructureElement heading =
section.AddChildElement(Pdf17StructureType.H1);
heading.AddFragment(page, new TextFragment
{
Text = "Invoice",
Location = new PointF(50, 800),
Font = new TextFont("Arial", TextFontStyle.Bold),
FontSize = 24
});
// Create a table with layout attributes.
StructureElement table =
section.AddChildElement(Pdf17StructureType.Table);
table.Attributes.Add(new LayoutAttribute
{
Placement = LayoutPlacement.Block,
WritingMode = WritingMode.LeftToRight
});
table.Attributes.Add(
new TableAttribute { Summary = "Invoice items" });
StructureElement header =
table.AddChildElement(Pdf17StructureType.THead);
StructureElement headerRow =
header.AddChildElement(Pdf17StructureType.TR);
// Add table header cells.
StructureElement th1 =
headerRow.AddChildElement(Pdf17StructureType.TH);
th1.Attributes.Add(
new TableAttribute { Scope = TableScope.Column });
th1.AddFragment(page, new TextFragment
{
Text = "Item",
Location = new PointF(50, 700),
Font = new TextFont("Arial", TextFontStyle.Bold),
FontSize = 12
});
StructureElement th2 =
headerRow.AddChildElement(Pdf17StructureType.TH);
th2.Attributes.Add(
new TableAttribute { Scope = TableScope.Column });
th2.AddFragment(page, new TextFragment
{
Text = "Qty",
Location = new PointF(250, 700),
Font = new TextFont("Arial", TextFontStyle.Bold),
});
StructureElement th3 =
headerRow.AddChildElement(Pdf17StructureType.TH);
th3.Attributes.Add(
new TableAttribute { Scope = TableScope.Column });
th3.AddFragment(page, new TextFragment
{
Text = "Price",
Location = new PointF(320, 700),
Font = new TextFont("Arial", TextFontStyle.Bold)
});
StructureElement th4 =
headerRow.AddChildElement(Pdf17StructureType.TH);
th4.Attributes.Add(
new TableAttribute { Scope = TableScope.Column });
th4.AddFragment(page, new TextFragment
{
Text = "Total",
Location = new PointF(400, 700),
Font = new TextFont("Arial", TextFontStyle.Bold),
});
// Add table body with a data row.
StructureElement body =
table.AddChildElement(Pdf17StructureType.TBody);
StructureElement dataRow =
body.AddChildElement(Pdf17StructureType.TR);
StructureElement td1 =
dataRow.AddChildElement(Pdf17StructureType.TD);
td1.AddFragment(page, new TextFragment
{
Text = "Product A",
Location = new PointF(50, 670)
});
StructureElement td2 =
dataRow.AddChildElement(Pdf17StructureType.TD);
td2.AddFragment(page, new TextFragment
{
Text = "2",
Location = new PointF(250, 670)
});
StructureElement td3 =
dataRow.AddChildElement(Pdf17StructureType.TD);
td3.AddFragment(page, new TextFragment
{
Text = "$25.00",
Location = new PointF(320, 670)
});
StructureElement td4 =
dataRow.AddChildElement(Pdf17StructureType.TD);
td4.AddFragment(page, new TextFragment
{
Text = "$50.00",
Location = new PointF(400, 670)
});
// Add a paragraph with the total amount.
StructureElement pTotal =
section.AddChildElement(Pdf17StructureType.P);
pTotal.AddFragment(page, new TextFragment
{
Text = "Total: $50.00",
Location = new PointF(50, 620),
Font = new TextFont("Arial", TextFontStyle.Bold),
});
// Save the tagged document.
using (FileStream stream =
File.Create("TaggedInvoice.pdf"))
{
document.Save(stream);
}
}
Manage Annotations
The PDF Document API supports the following annotation types:
- Markup Annotations
- Annotations used to mark up document content. The following markups are available:
- Non-Markup Annotations
The following code snippet opens the Invoice.pdf file, adds a TextAnnotation to the first page, and saves the file:

FileStream fs = File.OpenRead("Invoice.pdf");
var options = new LoadOptions();
PdfDocument document = new PdfDocument(fs, options);
TextAnnotation textAnnotation = new TextAnnotation(new RectangleF(85, 405, 20, 20)) {
Color = Color.Yellow,
Title = "Brian Zetc",
Content = "This is an excellent overview."
};
document.Pages[0].Annotations.Add(textAnnotation);
document.Save(new FileStream("Invoice2.pdf", FileMode.Create, FileAccess.Write));
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo("Invoice2.pdf") { UseShellExecute = true });
Work with Interactive Forms
Forms are a key component of many document workflows. The API exposes all form fields as strongly typed objects. You can create, edit, fill, and remove fields as needed. It is also possible to adjust field appearance using its WidgetAnnotation.
Supported field types include:
The following example finds form fields by name and sets associated values:
var nameField = (TextBoxField)document.Fields.FindByName("Name");
nameField.Value = "John Smith";
var checkBox = (CheckBoxField)document.Fields.FindByName("AcceptTerms");
checkBox.Checked = true;
Form data can be imported and exported in multiple formats:
- FDF
- XFDF
- XML
- TXT
document.ImportFormData(stream, ExportDataFormat.Xfdf);
document.ExportFormData(stream, ExportDataFormat.Xml);
Manage Document Metadata
Metadata plays a critical role in document indexing, searching, and compliance. Our PDF API offers full access to both traditional PDF metadata and structured XMP metadata via a unified interface.
The metadata model includes:
- DocumentInfo - standard fields such as Title, Author, Subject, Keywords
- XmpMetadata - structured metadata with multiple schemas:
To ensure consistency between PDF and XML metadata, use one of the following synchronization strategies:
- Synchronize metadata when opening a document. Specify LoadOptions.SyncMetadata and LoadOptions.MetadataSyncMode properties and pass the
LoadOptionsobject as aPdfDocumentconstructor parameter. - Enforce consistency on save. Specify SaveOptions.SyncMetadata and SaveOptions.MetadataSyncMode properties and pass the
SaveOptionsobject as thePdfDocument.Savemethod parameter. - Manually synchronize at any point. Call the DocumentMetadata.Synchronize method.
The following code snippet creates the Rights Management schema and embeds it into a PDF document:
using DevExpress.Docs.Pdf;
using System.IO;
using (PdfDocument pdfDocument =
new PdfDocument(File.OpenRead(@"document_001.pdf"))) {
// Create a new XMP packet:
XmpMetadata metadata = new XmpMetadata();
XmpRightsManagementSchema rightsManagementSchema =
metadata.XmpRightsManagementSchema;
rightsManagementSchema.Certificate = new XmpString("https://www.devexpress.com/");
rightsManagementSchema.Owner.Add(new XmpString("DevExpress"));
rightsManagementSchema.Marked = true;
rightsManagementSchema.WebStatement = new XmpString("https://www.devexpress.com/support/eulas/");
rightsManagementSchema.UsageTerms.Add("EN-US", "Copyright(C) 2026 DevExpress.All Rights Reserved.");
// Embed metadata in the document:
pdfDocument.Metadata.Xmp = metadata;
}