Word (RTF) to Accessible PDF

Use the Word Processing Document API to export a document to a tagged (accessible) PDF file. Click Select File and load a document in RTF, DOC, DOCX, MHT, ODT, XML, or HTML format. Select an output format from the list and click Download to save the result. The maximum file size you can upload is 1MB.

Convert file to:
@model AspNetCoreDemos.OfficeFileAPI.WordRTFAccessiblePDFModel
@using DevExtreme.AspNet.Mvc

@using(Html.BeginForm("WordRTFAccessiblePDFExportTo", "DocumentConversion", FormMethod.Post)) {
@Html.HiddenFor(model => model.DocumentUrl)
<script type="text/javascript">
    function fileUploader_valueChanged(e) {
        var files = e.value;
        if (files.length > 0) {
            $("#selected-files .selected-item").remove();

            $.each(files, function (i, file) {
                var $selectedItem = $("<div />").addClass("selected-item");
                $selectedItem.append(file.name);
                $selectedItem.appendTo($("#selected-files"));
            });

            $("#selected-files").show();

            $('#DocumentUrl').val(files[0].name);
            var button = $("#downloadButton").dxButton("instance");
            button.option("disabled", false);
        }
        else
            $("#selected-files").hide();
    }
    function UpdatePreview() {
        WordRTFPreview.Update("");
    }
    function DownloadClick() {
        document.getElementById("error").hidden = true;
    }
</script>

<div class="uploader-panel">
    @(Html.DevExtreme().FileUploader()
                       .ID("file-uploader")
                       .Name("myFile")
                       .Multiple(false)
                       .ShowFileList(true)
                       .Accept(".rtf, .doc, .docx, .txt, .mht, .odt, .xml, .epub, .htm, .html")
                       .MaxFileSize(1048576)
                       .UploadMode(FileUploadMode.Instantly)
                       .UploadUrl(Url.Action("DocumentUpload", "RichEditAccessiblePDF"))
                       .OnValueChanged("fileUploader_valueChanged")
                       .OnFilesUploaded("UpdatePreview"))
</div>

<div class="document-downloader" style="margin-bottom:10px">
    <div class="document-downloader-item">Convert file to:</div>
    <div class="document-downloader-format-selector">
        @(Html.DevExtreme().SelectBoxFor(m => m.PdfCompatibility)
                       .DataSource(new object[]
                                { new { Text = "PDF/A-1a", Value = "pdf/a-1a" },
                                    new { Text = "PDF/A-2a", Value = "pdf/a-2a" },
                                    new { Text = "PDF/A-3a", Value = "pdf/a-3a" },
                                    new { Text = "PDF/UA", Value = "pdf/ua" } })
                       .ValueExpr("Value")
                       .DisplayExpr("Text"))
    </div>
    <div class="document-downloader-item">
        @(Html.DevExtreme().Button()
                               .ID("downloadButton")
                               .Text("Download")
                               .Disabled(false)
                               .Type(ButtonType.Default)
                               .StylingMode(ButtonStylingMode.Contained)
                               .UseSubmitBehavior(true)
                               .OnClick("DownloadClick"))
    </div>
    <div id="error" class="error-message-right">
        <span>@ViewBag.ErrorMessage</span>
    </div>
</div>
<div class="demo-view-container" style="width:100%;box-sizing:border-box">
        @await Html.PartialAsync("WordRTFPreviewPartial", Model.PreviewModel)
</div>
}
@model AspNetCoreDemos.OfficeFileAPI.WordRTFPreviewModel

<iframe id="previewFrame" src="@Url.Action(Model.PreviewDocumentAction, Model.ControllerName)" height="@Model.IFrameSize" class="demo-preview-border" style="width:100%;box-sizing:border-box"></iframe>

<script type="text/javascript">
    WordRTFPreview = {
        basePath: '@Url.Action(Model.PreviewDocumentAction, Model.ControllerName)',
        Update: function (param) {
            var iframeElementName = "previewFrame";
            var iframeElement = document.getElementById(iframeElementName);
            if (!iframeElement)
                return;
            var additionalParams = "&" + new Date().valueOf();
            if (param)
                additionalParams = param;
            iframeElement.src = this.basePath + "?" + additionalParams;
        }
    };
</script>
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;

namespace AspNetCoreDemos.OfficeFileAPI {
    public partial class DocumentConversionController : DocumentProcessingController {
        public DocumentConversionController(ILogger<DocumentConversionController> logger, IWebHostEnvironment hostingEnvironment)
            : base(logger, hostingEnvironment) {
        }

        protected const string LoadDocumentExceptionString = "ERROR: Cannot convert this document.";
        protected override string SessionKey => throw new NotImplementedException();
    }
}
using System;
using System.IO;
using DevExpress.XtraPrinting;
using DevExpress.XtraRichEdit;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace AspNetCoreDemos.OfficeFileAPI {
    public class RichEditAccessiblePDFController: DocumentConversionController {
        public RichEditAccessiblePDFController(ILogger<RichEditAccessiblePDFController> logger, IWebHostEnvironment hostingEnvironment)
            : base(logger, hostingEnvironment) {
        }

        public static string RichEditSessionKey => "RichEditAccessiblePDFFileKey";
        protected override string SessionKey => RichEditSessionKey;
    }

    public partial class DocumentConversionController {
        public IActionResult WordRTFAccessiblePDF() {
            WordRTFAccessiblePDFModel model = new WordRTFAccessiblePDFModel();
            return View(model);
        }
        public IActionResult WordRTFAccessiblePDFPreview(WordRTFAccessiblePDFModel model) {
            Stream stream = CreateDocumentStream(model, DocumentFormat.Html);
            return CreatePreviewResult(stream);
        }
        [HttpPost]
        public IActionResult WordRTFAccessiblePDFExportTo(WordRTFAccessiblePDFModel model) {
            try {
                RichEditDocumentServer documentServer = CreateDocumentServerAndLoadDocument(model);
                MemoryStream stream = new MemoryStream();
                RichEditFileFormat documentType = RichEditFileFormat.Pdf;
                string format = model.PdfCompatibility;
                PdfExportOptions exportOptions = new PdfExportOptions();
                if(format == "pdf/a-1a") {
                    exportOptions.PdfACompatibility = PdfACompatibility.PdfA1a;
                } else if(format == "pdf/a-2a") {
                    exportOptions.PdfACompatibility = PdfACompatibility.PdfA2a;
                } else if(format == "pdf/a-3a") {
                    exportOptions.PdfACompatibility = PdfACompatibility.PdfA3a;
                } else if(format == "pdf/ua") {
                    exportOptions.PdfUACompatibility = PdfUACompatibility.PdfUA1;
                }
                exportOptions.ConvertImagesToJpeg = false;
                documentServer.ExportToPdf(stream, exportOptions);

                string contentType = WordRTFUtils.ConvertToContentType(documentType);
                string fileExtension = WordRTFUtils.ConvertToFileExtension(documentType);
                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Uri.UnescapeDataString(model.DocumentUrl));
                return CreateFileStreamResult(stream, contentType, fileExtension, fileNameWithoutExtension);
            } catch(Exception ex) {
                Logger.LogError(ex, LoadDocumentExceptionString);
                ViewBag.ErrorMessage = LoadDocumentExceptionString;
                return View(model);
            }
        }
        Stream CreateDocumentStream(WordRTFAccessiblePDFModel model, DocumentFormat documentFormat) {
            if(documentFormat == DocumentFormat.Undefined)
                return null;
            RichEditDocumentServer documentServer = CreateDocumentServerAndLoadDocument(model);
            MemoryStream result = new MemoryStream();
            documentServer.SaveDocument(result, documentFormat);
            result.Seek(0, SeekOrigin.Begin);
            return result;
        }
        RichEditDocumentServer CreateDocumentServerAndLoadDocument(WordRTFAccessiblePDFModel model) {
            RichEditDocumentServer documentServer = CreateDocumentServer();
            try {
                byte[] data;
                if(HttpContext.Session.TryGetValue(RichEditAccessiblePDFController.RichEditSessionKey, out data))
                    documentServer.LoadDocument(data);
                else {
                    string filePath = HostingEnvironment.ContentRootPath + model.DocumentUrl;
                    documentServer.LoadDocument(filePath);
                }
            } catch(Exception ex) {
                Logger.LogError(ex, LoadDocumentExceptionString);
                ViewBag.ErrorMessage = LoadDocumentExceptionString;
            }
            return documentServer;
        }
        RichEditDocumentServer CreateDocumentServer() {
            RichEditDocumentServer documentServer = new RichEditDocumentServer();
            documentServer.Options.Export.Html.EmbedImages = true;
            return documentServer;
        }
    }
}
namespace AspNetCoreDemos.OfficeFileAPI {
    public class WordRTFAccessiblePDFModel: WordRTFModelBase {
        public WordRTFAccessiblePDFModel() {
            PreviewModel.PreviewDocumentAction = "WordRTFAccessiblePDFPreview";
            PreviewModel.ControllerName = "DocumentConversion";
            DocumentUrl = "/Documents/DocumentForProtection.docx";
            FileFormat = RichEditFileFormat.Docx;
            PdfCompatibility = "pdf/a-3a";
        }

        public string PdfCompatibility { get; set; }
        public string DocumentUrl { get; set; }
    }
}
namespace AspNetCoreDemos.OfficeFileAPI {
    public class WordRTFModelBase {
        public WordRTFModelBase() {
            PreviewModel = new WordRTFPreviewModel();
            PreviewModel.OwnerPropertyName = "PreviewModel";
            FileFormat = RichEditFileFormat.Rtf;
        }

        public RichEditFileFormat FileFormat { get; set; }
        public WordRTFPreviewModel PreviewModel { get; internal set; }
    }

    public class WordRTFPreviewModel {
        public WordRTFPreviewModel() {
        }

        public string OwnerPropertyName { get; set; }
        public string PreviewDocumentAction { get; set; }
        public string ControllerName { get; set; }
        public int IFrameSize { get; set; } = 452;
    }
}