Create Word (DOCX) or PDF files in ASP.NET Core

With GemBox.Document you can build web applications that target ASP.NET Core 2.0 and above by simply installing it with NuGet or adding the following package reference in the project file.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="GemBox.Document" Version="*" />

    <!--
      For saving to PDF or image format on Linux, add native assets.
    -->
    <!--<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="*" />-->
    <!--<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="*" />-->
  </ItemGroup>

</Project>

The following live demos and code examples show how to use GemBox.Document to create ASP.NET Core web applications that generate and download Word and PDF files to your browser.

Create Word or PDF files in ASP.NET Core MVC

The following example shows how you can create an ASP.NET Core MVC application that:

  1. Imports data from a web form into a Word document using the Mail Merge process.
  2. Creates a file of a specified format like DOCX or PDF.
  3. Downloads the generated file with a FileStreamResult.
Importing data from Razor view and generating DOCX file in ASP.NET Core MVC application
Screenshot of submitted web form and created Word document
@model InvoiceModel

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>GemBox.Document in ASP.NET Core MVC application</title>
    <link rel="icon" href="~/favicon.ico" />
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-controller="Home" asp-action="Index">Home</a>
            </div>
        </nav>
    </header>

    <div class="container">
        <main class="pb-3 row">
            <h1 class="display-4 p-3">Invoice generator [Razor View]</h1>
            <div class="col-lg-6">
                <form asp-action="Download">
                    <div class="form-group">Number: <input asp-for="Number" class="form-control" /></div>
                    <div class="form-group">Date: <input asp-for="Date" class="form-control" /></div>
                    <div class="form-group">Company: <input asp-for="Company" class="form-control" /></div>
                    <div class="form-group">Address: <input asp-for="Address" class="form-control" /></div>
                    <div class="form-group">Name: <input asp-for="Name" class="form-control" /></div>
                    <div class="form-group">
                        Format:
                        <div class="row">
                            @foreach (string format in Model.FormatMappingDictionary.Select(item => item.Key))
                            {
                                <div class="col-3">
                                    <div class="form-check form-check-inline">
                                        <input asp-for="Format" class="form-check-input" type="radio" id="@format" value="@format">
                                        <label for="@format" class="form-check-label">@format</label>
                                    </div>
                                </div>
                            }
                        </div>
                    </div>
                    <div class="form-group"><input type="submit" value="Create" class="btn btn-primary" /></div>
                </form>
            </div>
        </main>
    </div>

    <footer class="footer border-top text-muted">
        <div class="container">&copy; GemBox Ltd. — All rights reserved.</div>
    </footer>
</body>
</html>
using DocumentCoreMvc.Models;
using GemBox.Document;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace DocumentCoreMvc.Controllers
{
    public class HomeController : Controller
    {
        private readonly IWebHostEnvironment environment;

        // If using the Professional version, put your serial key below.
        static HomeController() => ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        public HomeController(IWebHostEnvironment environment) => this.environment = environment;

        public IActionResult Index() => this.View(new InvoiceModel());

        public FileStreamResult Download(InvoiceModel model)
        {
            // Load template document.
            var path = Path.Combine(this.environment.ContentRootPath, "InvoiceWithFields.docx");
            var document = DocumentModel.Load(path);

            // Execute mail merge process.
            document.MailMerge.Execute(model);

            // Save document in specified file format.
            var stream = new MemoryStream();
            document.Save(stream, model.Options);

            // Download file.
            return File(stream, model.Options.ContentType, $"OutputFromView.{model.Format.ToLower()}");
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error() => 
            this.View(new ErrorViewModel() { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

namespace DocumentCoreMvc.Models
{
    public class InvoiceModel
    {
        public int Number { get; set; } = 1;
        public DateTime Date { get; set; } = DateTime.Today;
        public string Company { get; set; } = "ACME Corp.";
        public string Address { get; set; } = "240 Old Country Road, Springfield, United States";
        public string Name { get; set; } = "Joe Smith";
        public string Format { get; set; } = "DOCX";
        public SaveOptions Options => this.FormatMappingDictionary[this.Format];
        public IDictionary<string, SaveOptions> FormatMappingDictionary => new Dictionary<string, SaveOptions>()
        {
            ["PDF"] = new PdfSaveOptions(),
            ["DOCX"] = new DocxSaveOptions(),
            ["ODT"] = new OdtSaveOptions(),
            ["HTML"] = new HtmlSaveOptions() { EmbedImages = true },
            ["MHTML"] = new HtmlSaveOptions() { HtmlType = HtmlType.Mhtml },
            ["RTF"] = new RtfSaveOptions(),
            ["XML"] = new XmlSaveOptions(),
            ["TXT"] = new TxtSaveOptions(),
            ["XPS"] = new XpsSaveOptions(), // XPS is supported only on Windows.
            ["PNG"] = new ImageSaveOptions(ImageSaveFormat.Png),
            ["JPG"] = new ImageSaveOptions(ImageSaveFormat.Jpeg),
            ["BMP"] = new ImageSaveOptions(ImageSaveFormat.Bmp),
            ["GIF"] = new ImageSaveOptions(ImageSaveFormat.Gif),
            ["TIF"] = new ImageSaveOptions(ImageSaveFormat.Tiff),
            ["SVG"] = new ImageSaveOptions(ImageSaveFormat.Svg)
        };
    }
}

Create Word or PDF files in ASP.NET Core Razor Pages

The following example shows how you can create an ASP.NET Core Razor Pages application that:

  1. Imports data from a web form into a Word document using Find and Replace operations.
  2. Creates a file of a specified format like DOCX or PDF.
  3. Downloads the generated file with a FileContentResult.
Importing data from Razor page and generating PDF file in ASP.NET Core Razor Pages application
Screenshot of submitted web form and created PDF document
@page
@model IndexModel

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>GemBox.Document in ASP.NET Core Razor Pages application</title>
    <link rel="icon" href="~/favicon.ico" />
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-page="/Index">Home</a>
            </div>
        </nav>
    </header>

    <div class="container">
        <main class="pb-3 row">
            <h1 class="display-4 p-3">Invoice generator [Razor Page]</h1>
            <div class="col-lg-6">
                <form method="post">
                    <div class="form-group">Number: <input asp-for="Invoice.Number" class="form-control" /></div>
                    <div class="form-group">Date: <input asp-for="Invoice.Date" class="form-control" /></div>
                    <div class="form-group">Company: <input asp-for="Invoice.Company" class="form-control" /></div>
                    <div class="form-group">Address: <input asp-for="Invoice.Address" class="form-control" /></div>
                    <div class="form-group">Name: <input asp-for="Invoice.Name" class="form-control" /></div>
                    <div class="form-group">
                        Format:
                        <div class="row">
                            @foreach (string format in Model.Invoice.FormatMappingDictionary.Select(item => item.Key))
                            {
                                <div class="col-3">
                                    <div class="form-check form-check-inline">
                                        <input asp-for="Invoice.Format" class="form-check-input" type="radio" id="@format" value="@format">
                                        <label for="@format" class="form-check-label">@format</label>
                                    </div>
                                </div>
                            }
                        </div>
                    </div>
                    <div class="form-group"><input type="submit" value="Create" class="btn btn-primary" /></div>
                </form>
            </div>
        </main>
    </div>

    <footer class="footer border-top text-muted">
        <div class="container">&copy; GemBox Ltd. — All rights reserved.</div>
    </footer>
</body>
</html>
using DocumentCorePages.Models;
using GemBox.Document;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.Collections.Generic;
using System.IO;

namespace DocumentCorePages.Pages
{
    public class IndexModel : PageModel
    {
        private readonly IWebHostEnvironment environment;

        [BindProperty]
        public InvoiceModel Invoice { get; set; }

        // If using the Professional version, put your serial key below.
        static IndexModel() => ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        public IndexModel(IWebHostEnvironment environment)
        {
            this.environment = environment;
            this.Invoice = new InvoiceModel();
        }

        public void OnGet() { }

        public FileContentResult OnPost()
        {
            // Load template document.
            var path = Path.Combine(this.environment.ContentRootPath, "InvoiceWithPlaceholders.docx");
            var document = DocumentModel.Load(path);

            // Execute find and replace operations.
            document.Content.Replace("{{Number}}", this.Invoice.Number.ToString("0000"));
            document.Content.Replace("{{Date}}", this.Invoice.Date.ToString("d MMM yyyy HH:mm"));
            document.Content.Replace("{{Company}}", this.Invoice.Company);
            document.Content.Replace("{{Address}}", this.Invoice.Address);
            document.Content.Replace("{{Name}}", this.Invoice.Name);

            // Save document in specified file format.
            using var stream = new MemoryStream();
            document.Save(stream, this.Invoice.Options);

            // Download file.
            return File(stream.ToArray(), this.Invoice.Options.ContentType, $"OutputFromPage.{this.Invoice.Format.ToLower()}");
        }
    }
}

namespace DocumentCorePages.Models
{
    public class InvoiceModel
    {
        public int Number { get; set; } = 1;
        public DateTime Date { get; set; } = DateTime.Today;
        public string Company { get; set; } = "ACME Corp.";
        public string Address { get; set; } = "240 Old Country Road, Springfield, United States";
        public string Name { get; set; } = "Joe Smith";
        public string Format { get; set; } = "PDF";
        public SaveOptions Options => this.FormatMappingDictionary[this.Format];
        public IDictionary<string, SaveOptions> FormatMappingDictionary => new Dictionary<string, SaveOptions>()
        {
            ["PDF"] = new PdfSaveOptions(),
            ["DOCX"] = new DocxSaveOptions(),
            ["ODT"] = new OdtSaveOptions(),
            ["HTML"] = new HtmlSaveOptions() { EmbedImages = true },
            ["MHTML"] = new HtmlSaveOptions() { HtmlType = HtmlType.Mhtml },
            ["RTF"] = new RtfSaveOptions(),
            ["XML"] = new XmlSaveOptions(),
            ["TXT"] = new TxtSaveOptions(),
            ["XPS"] = new XpsSaveOptions(), // XPS is supported only on Windows.
            ["PNG"] = new ImageSaveOptions(ImageSaveFormat.Png),
            ["JPG"] = new ImageSaveOptions(ImageSaveFormat.Jpeg),
            ["BMP"] = new ImageSaveOptions(ImageSaveFormat.Bmp),
            ["GIF"] = new ImageSaveOptions(ImageSaveFormat.Gif),
            ["TIF"] = new ImageSaveOptions(ImageSaveFormat.Tiff),
            ["SVG"] = new ImageSaveOptions(ImageSaveFormat.Svg)
        };
    }
}

Host and deploy ASP.NET Core

When hosting an ASP.NET Core application that uses GemBox.Document, specific adjustments are necessary for Windows Server or Linux. Detailed instructions for these adjustments are available on the supported platforms help page.

It is recommended to review the Private Fonts example when deploying an ASP.NET Core application using GemBox.Document on Linux to make sure that font styles and formatting are handled correctly.

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