SelectPdf for .NET 10 - Accessible Pdf (PDF/UA) - C# / .NET 10 Sample

A tagged pdf carries a logical structure tree - headings, paragraphs, lists, tables, figures with alternate text, links and the reading order - which assistive technologies such as screen readers use to present the document. Decorative content is marked as an artifact so it is skipped.

Setting AccessibilityStandard declares conformance with PDF/UA-1 or PDF/UA-2: it turns tagging on and writes the identifier validators look for. Setting Tagged alone builds the structure without making that claim. Both standards require a title and a language, so the sample sets them as well.

The structure comes from the html, so how accessible the result is depends on the page: images need an alt attribute, headings should be used in order, tables should use real table markup.

Url:


Document title (required for an accessible pdf):


Document language:


Accessibility standard:




Sample code · C#
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using SelectPdf.Universal;

namespace SelectPdf.Samples.Pages
{
    public class AccessiblePdfModel : PageModel
    {
        public void OnGet()
        {
            TxtUrl = "https://selectpdf.com";
            TxtTitle = "SelectPdf - accessible document";
            TxtLanguage = "en-US";
            DdlStandard = "UA1";
        }

        [BindProperty]
        public string TxtUrl { get; set; }

        [BindProperty]
        public string TxtTitle { get; set; }

        [BindProperty]
        public string TxtLanguage { get; set; }

        [BindProperty]
        public string DdlStandard { get; set; } = "UA1";

        public List<SelectListItem> Standards { get; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "UA1", Text = "PDF/UA-1 (ISO 14289-1)" },
            new SelectListItem { Value = "UA2", Text = "PDF/UA-2 (ISO 14289-2, PDF 2.0)" },
        };

        public IActionResult OnPost()
        {
            try
            {
                // instantiate a html to pdf converter object
                HtmlToPdf converter = new HtmlToPdf();
                converter.Options.NavigationTimeout = Startup.NavigationTimeout;

                // declare the accessibility standard the document conforms to - this turns tagging on
                // and writes the PDF/UA identifier. Setting Tagged alone would build the structure tree
                // without declaring conformance.
                converter.Options.AccessibilityStandard =
                    SampleForm.ParseEnum(DdlStandard, PdfUAStandard.UA1);

                // an accessible document is required to declare a title and a language
                converter.Options.Title = TxtTitle;
                converter.Options.Language = TxtLanguage;

                // create a new pdf document converting an url
                PdfDocument doc = converter.ConvertUrl(TxtUrl);

                // save pdf document
                byte[] pdf = doc.Save();

                // close pdf document
                doc.Close();

                // return resulted pdf document
                FileResult fileResult = new FileContentResult(pdf, "application/pdf");
                fileResult.FileDownloadName = "AccessibleDocument.pdf";
                return fileResult;
            }
            catch (Exception ex)
            {
                // a document that cannot be produced to the chosen standard is refused with the reason;
                // show it on the page rather than as a server error
                ViewData["Message"] = "An error occurred: " + ex.Message;
                return Page();
            }
        }
    }
}