Creating Accessible PDF Documents Q3 2025 (or newer)
Related Feature: | Accessibility Support |
---|
This article aims to demonstrate how to generate an accessible PDF document using Telerik Document Processing.
To take advantage of the accessibility feature, the document must be PDF/A-1a, PDF/A-2a, PDF/A-3a, or PDF/UA-1 compliant. To achieve this, the PdfComplianceLevel and TaggingStrategy properties of the PdfFormatProvider's PdfExportSettings must be set accordingly.
RadFixedDocument offers a constructor allowing to specify the AutoTag property value which is false by default. This gives the developer the opportunity to choose whether to build the StructureTree from scratch or leave the library auto-tag the elements.
Please refer to the PdfProcessing Accessibility Demo which demonstrates how to create accessible PDF documents programmatically, ensuring compliance with standards such as PDF/UA by supporting features like tagged content, document structure, and metadata. Downloaded documents will adhere to the selected compliance level.
In .NET Standard/.NET (Target OS: None) environments, fonts beyond the 14 standard ones require a FontsProvider implementation to be resolved correctly.
Creating Accessible PDF Documents and Building the StructureTree
When exporting the document, specify the TaggingStrategy so the document should not be tagged automatically and use the existing StructureTree:
//Required for exporting images in .NET Standard
//Telerik.Documents.ImageUtils.ImagePropertiesResolver defaultImagePropertiesResolver = new Telerik.Documents.ImageUtils.ImagePropertiesResolver();
//Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.ImagePropertiesResolver = defaultImagePropertiesResolver;
RadFixedDocument fixedDocument = new RadFixedDocument(autoTag: false);
fixedDocument.DocumentInfo.Title = "Accessible Document Example";
fixedDocument.ViewerPreferences.ShouldDisplayDocumentTitle = true;
StructureElement documentStructureElement = fixedDocument.StructureTree.ChildElements.AddStructureElement(StructureTagType.Document);
StructureElement sectionStructureElement = documentStructureElement.ChildElements.AddStructureElement(StructureTagType.Section);
StructureElement paragraphStructureElement1 = sectionStructureElement.ChildElements.AddStructureElement("CustomParagraph", StructureTagType.Paragraph);
StructureElement paragraphStructureElement2 = sectionStructureElement.ChildElements.AddStructureElement(StructureTagType.Paragraph);
StructureElement figureStructureElement = sectionStructureElement.ChildElements.AddStructureElement(StructureTagType.Figure);
RadFixedPage fixedPage = fixedDocument.Pages.AddPage();
MarkedContent paragraphContainer1 = fixedPage.Content.AddMarkedContent();
TextFragment textFragment1 = paragraphContainer1.Content.AddTextFragment("Text fragment 1");
textFragment1.Font = FontsRepository.Courier;
textFragment1.Position.Translate(20, 20);
paragraphContainer1.StructureTag = paragraphStructureElement1;
paragraphStructureElement1.AlternateDescription = "Standard Paragraph in English";
paragraphStructureElement1.Language = "EN";
paragraphStructureElement1.ActualText = "Text fragment 1";
MarkedContent paragraphContainer2 = fixedPage.Content.AddMarkedContent();
TextFragment textFragment2 = paragraphContainer2.Content.AddTextFragment("Fragmento de texto 2");
textFragment2.Font = FontsRepository.Courier;
textFragment2.Position.Translate(20, 100);
paragraphContainer2.StructureTag = paragraphStructureElement2;
paragraphStructureElement2.Language = "ES";
paragraphStructureElement2.AlternateDescription = "Custom Paragraph in Spanish";
paragraphStructureElement2.ActualText = "Fragmento de texto 2";
MarkedContent imageContainer1 = fixedPage.Content.AddMarkedContent();
figureStructureElement.Language = "EN";
figureStructureElement.AlternateDescription = "Image of a Telerik Ninja";
figureStructureElement.ActualText = "Telerik Ninja logo";
Image img = imageContainer1.Content.AddImage();
img.Position.Translate(100, 200);
img.ImageSource = new Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource(
File.OpenRead(@"ProgressNinjas.png"));
imageContainer1.StructureTag = figureStructureElement;
figureStructureElement.AlternateDescription = "Progress Ninja";
PdfFormatProvider provider = new PdfFormatProvider();
PdfExportSettings settings = new PdfExportSettings();
provider.ExportSettings = settings;
settings.TaggingStrategy = TaggingStrategyType.UseExisting;
settings.ComplianceLevel = PdfComplianceLevel.PdfUA1;
string outputFilePath = "AccessibleDocument.pdf";
File.Delete(outputFilePath);
using (Stream output = File.OpenWrite(outputFilePath))
{
provider.Export(fixedDocument, output, TimeSpan.FromSeconds(10));
}
Process.Start(new ProcessStartInfo() { FileName = outputFilePath, UseShellExecute = true });
PDF Accessibility Checker tool | Logical Structure |
---|---|
![]() |
![]() |
![]() |
Creating Accessible PDF Documents with Auto-Tagging
This example shows how to add content to a PDF doocument and leave the PdfProcessing's engine build the StructureTree automatically:
//Required for exporting images in .NET Standard
//Telerik.Documents.ImageUtils.ImagePropertiesResolver defaultImagePropertiesResolver = new Telerik.Documents.ImageUtils.ImagePropertiesResolver();
//Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.ImagePropertiesResolver = defaultImagePropertiesResolver;
RadFixedDocument fixedDocument = new RadFixedDocument(autoTag: true);
fixedDocument.DocumentInfo.Title = "Accessible Document Example";
fixedDocument.ViewerPreferences.ShouldDisplayDocumentTitle = true;
RadFixedPage fixedPage = fixedDocument.Pages.AddPage();
MarkedContent paragraphContainer1 = fixedPage.Content.AddMarkedContent();
TextFragment textFragment1 = paragraphContainer1.Content.AddTextFragment("Text fragment 1");
textFragment1.Font = FontsRepository.Courier;
textFragment1.Position.Translate(20, 20);
MarkedContent paragraphContainer2 = fixedPage.Content.AddMarkedContent();
TextFragment textFragment2 = paragraphContainer2.Content.AddTextFragment("Fragmento de texto 2");
textFragment2.Font = FontsRepository.Courier;
textFragment2.Position.Translate(20, 100);
MarkedContent imageContainer1 = fixedPage.Content.AddMarkedContent();
Image img = imageContainer1.Content.AddImage();
img.Position.Translate(100, 200);
img.ImageSource = new Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource(
File.OpenRead(@"ProgressNinjas.png"));
PdfFormatProvider provider = new PdfFormatProvider();
PdfExportSettings settings = new PdfExportSettings();
provider.ExportSettings = settings;
settings.TaggingStrategy = TaggingStrategyType.Build;
settings.ComplianceLevel = PdfComplianceLevel.PdfUA1;
string outputFilePath = "AccessibleDocumentAuto.pdf";
File.Delete(outputFilePath);
using (Stream output = File.OpenWrite(outputFilePath))
{
provider.Export(fixedDocument, output, TimeSpan.FromSeconds(10));
}
Process.Start(new ProcessStartInfo() { FileName = outputFilePath, UseShellExecute = true });