Word Editor in ASP.NET MVC

GemBox.Document is a standalone .NET component that's ideal for web applications (like ASP.NET MVC, ASP.NET Core, and ASP.NET Web Forms) because of its fast performance and thread safety when working with multiple DocumentModel objects.

GemBox.Document supports reading and writing documents from or to Stream, so you can easily load a document that's uploaded to server and save the resulting document to browser by downloading it.

Also, GemBox.Document supports both reading and writing HTML content, which enables you to combine it with any WYSIWYG HTML editor in order to create an advanced online Word editor, one that's capable of saving to PDF, combining multiple documents, executing a mail merge process and a lot more.

The following example shows interoperability between GemBox.Document library and TinyMCE control from an ASP.NET MVC application. Note, you can use the same approach with any rich text editor like CKEditor, Quill, etc.

Word editor that combines WYSIWYG HTML editor and GemBox.Document in ASP.NET MVC demo application
Screenshot of rich text editor for Word files in ASP.NET MVC
Generated and downloaded PDF document from template Word document in ASP.NET MVC demo application
Screenshot of downloaded PDF file in ASP.NET MVC
@model AspNetWordEditor.FileModel

<!DOCTYPE html>
<html lang="en-US">
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Word Editor in ASP.NET MVC</title>
    <script src="~/scripts/tinymce/tinymce.min.js"></script>
    <script>
        tinyMCE.init({
            selector: "textarea#file-editor",
            height: 400,
            setup: (editor) => editor.on('init', () =>
                editor.setContent("<p>Welcome to ASP.NET MVC demo that uses <strong>GemBox.Document</strong> library and <strong>TinyMCE</strong> editor.</p>")),
        });
    </script>
    <style>
        body {
            font-family: Calibri;
            color: #514E52;
        }

        form { max-width: 800px; }

        #file-generator * {
            padding: 10px;
            margin: 10px
        }
    </style>
</head>
<body>
    @using (Html.BeginForm("Download", "Home"))
    {
        @Html.AntiForgeryToken()

        @Html.TextAreaFor(model => model.Content, new { id = "file-editor" })

        <div id="file-generator">
            <input type="submit" value="Download" />
            as
            @Html.DropDownListFor(model => model.Extension,
                new[]
                {
                    new SelectListItem() { Text = "PDF", Value = ".pdf", Selected = true },
                    new SelectListItem() { Text = "DOCX", Value = ".docx" },
                    new SelectListItem() { Text = "ODT", Value = ".odt" },
                    new SelectListItem() { Text = "HTML", Value = ".html" },
                    new SelectListItem() { Text = "MHTML", Value = ".mhtml" },
                    new SelectListItem() { Text = "RTF", Value = ".rtf" },
                    new SelectListItem() { Text = "XML", Value = ".xml" },
                    new SelectListItem() { Text = "TXT", Value = ".txt" },
                    new SelectListItem() { Text = "XPS", Value = ".xps" },
                    new SelectListItem() { Text = "PNG", Value = ".png" },
                    new SelectListItem() { Text = "JPEG", Value = ".jpeg" },
                    new SelectListItem() { Text = "GIF", Value = ".gif" },
                    new SelectListItem() { Text = "BMP", Value = ".bmp" },
                    new SelectListItem() { Text = "TIFF", Value = ".tiff" },
                    new SelectListItem() { Text = "WMP", Value = ".wmp" },
                    new SelectListItem() { Text = "SVG", Value = ".svg" }
                })
        </div>
    }
</body>
</html>
using System.IO;
using System.Web.Mvc;
using GemBox.Document;

namespace AspNetWordEditor
{
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index() => this.View(new FileModel());

        [HttpPost]
        public FileResult Download(FileModel model)
        {
            // If using the Professional version, put your serial key below.
            ComponentInfo.SetLicense("FREE-LIMITED-KEY");

            var templateFile = Server.MapPath("~/App_Data/%#DocumentTemplate.docx%");

            // Load template document.
            var document = DocumentModel.Load(templateFile);

            // Insert content from HTML editor.
            var bookmark = document.Bookmarks["HtmlBookmark"];
            bookmark.GetContent(true).LoadText(model.Content, LoadOptions.HtmlDefault);

            // Save document to stream in specified format.
            var saveOptions = GetSaveOptions(model.Extension);
            var stream = new MemoryStream();
            document.Save(stream, saveOptions);

            // Download document.
            var downloadFile = $"Output{model.Extension}";
            return File(stream.ToArray(), saveOptions.ContentType, downloadFile);
        }

        private static SaveOptions GetSaveOptions(string extension)
        {
            switch (extension)
            {
                case ".pdf": return SaveOptions.PdfDefault;
                case ".docx": return SaveOptions.DocxDefault;
                case ".odt": return SaveOptions.OdtDefault;
                case ".html": return SaveOptions.HtmlDefault;
                case ".mhtml": return new HtmlSaveOptions() { HtmlType = HtmlType.Mhtml };
                case ".rtf": return SaveOptions.RtfDefault;
                case ".xml": return SaveOptions.XmlDefault;
                case ".xps": return SaveOptions.XpsDefault;
                case ".png": return SaveOptions.ImageDefault;
                case ".jpeg": return new ImageSaveOptions(ImageSaveFormat.Jpeg);
                case ".bmp": return new ImageSaveOptions(ImageSaveFormat.Bmp);
                case ".gif": return new ImageSaveOptions(ImageSaveFormat.Gif);
                case ".tiff": return new ImageSaveOptions(ImageSaveFormat.Tiff);
                case ".wmp": return new ImageSaveOptions(ImageSaveFormat.Wmp);
                case ".svg": return new ImageSaveOptions(ImageSaveFormat.Svg);
                default: return SaveOptions.TxtDefault;
            }
        }
    }

    public sealed class FileModel
    {
        [AllowHtml]
        public string Content { get; set; }
        public string Extension { get; set; }
    }
}
Imports System.IO
Imports System.Web.Mvc
Imports GemBox.Document

Namespace AspNetWordEditor
    Public Class HomeController
        Inherits Controller

        <HttpGet>
        Function Index() As ActionResult
            Return View(New FileModel())
        End Function

        <HttpPost>
        Function Download(model As FileModel) As FileResult

            ' If using the Professional version, put your serial key below.
            ComponentInfo.SetLicense("FREE-LIMITED-KEY")

            Dim templateFile = Server.MapPath("~/App_Data/%#DocumentTemplate.docx%")

            ' Load template document.
            Dim document = DocumentModel.Load(templateFile)

            ' Insert content from HTML editor.
            Dim bookmark = document.Bookmarks("HtmlBookmark")
            bookmark.GetContent(True).LoadText(model.Content, LoadOptions.HtmlDefault)

            ' Save document to stream in specified format.
            Dim saveOptions = GetSaveOptions(model.Extension)
            Dim stream As New MemoryStream()
            document.Save(stream, saveOptions)

            ' Download document.
            Dim downloadFile = $"Output{model.Extension}"
            Return File(stream.ToArray(), saveOptions.ContentType, downloadFile)

        End Function

        Private Shared Function GetSaveOptions(extension As String) As SaveOptions
            Select Case extension
                Case ".pdf"
                    Return SaveOptions.PdfDefault
                Case ".docx"
                    Return SaveOptions.DocxDefault
                Case ".odt"
                    Return SaveOptions.OdtDefault
                Case ".html"
                    Return SaveOptions.HtmlDefault
                Case ".mhtml"
                    Return New HtmlSaveOptions() With {.HtmlType = HtmlType.Mhtml}
                Case ".rtf"
                    Return SaveOptions.RtfDefault
                Case ".xml"
                    Return SaveOptions.XmlDefault
                Case ".xps"
                    Return SaveOptions.XpsDefault
                Case ".png"
                    Return SaveOptions.ImageDefault
                Case ".jpeg"
                    Return New ImageSaveOptions(ImageSaveFormat.Jpeg)
                Case ".gif"
                    Return New ImageSaveOptions(ImageSaveFormat.Gif)
                Case ".bmp"
                    Return New ImageSaveOptions(ImageSaveFormat.Bmp)
                Case ".tiff"
                    Return New ImageSaveOptions(ImageSaveFormat.Tiff)
                Case ".wmp"
                    Return New ImageSaveOptions(ImageSaveFormat.Wmp)
                Case ".svg"
                    Return New ImageSaveOptions(ImageSaveFormat.Svg)
                Case Else
                    Return SaveOptions.TxtDefault
            End Select
        End Function

    End Class

    Public NotInheritable Class FileModel
        <AllowHtml>
        Public Property Content As String
        Public Property Extension As String
    End Class
End Namespace

Host and deploy ASP.NET MVC

GemBox.Document follows a licensing model per individual developer, which includes royalty-free deployment. You are allowed to build an unlimited number of applications and deploy or distribute them across numerous services, servers, or end-user machines without any additional cost. For more information, read our End User License Agreement (EULA).

See also


Next steps

GemBox.Document is a .NET component that enables you to read, write, edit, convert, and print document files from your .NET applications using one simple API. How about testing it today?

Download Buy