Convert Word DOCX to PDF

The Word to PDF Converter component of the library allows you to convert Word documents in DOCX format to PDF. You can preserve the original layout of the Word document or apply your own PDF page size, orientation and margins. The converter also supports HTML headers and footers, page break recognition and multiple output options.

Overview

The HiQPdf.ChromiumWordToPdfConverter class allows you to load a DOCX file and generate a PDF document, with optional control over page formatting, layout and visual elements such as headers and footers.

Create the Word to PDF Converter

The HiQPdf.ChromiumWordToPdfConverter class is used to convert DOCX documents to PDF. You can create an instance using the default constructor, which initializes the converter with standard settings. These settings can later be customized through the WordToPdfConverterPdfDocumentOptions and WordToPdfConverterProcessPageBreakMarks properties.

Create a Word to PDF Converter Instance
// Create a new Word to PDF converter instance
WordToPdfConverter wordToPdfConverter = new WordToPdfConverter();

Note that WordToPdfConverter instances are not reusable. You must create a new instance for each conversion. Reusing an instance after a completed conversion will result in an exception.

Configure the PDF Page Settings

The format of the generated PDF document pages is controlled primarily by the WordToPdfDocumentOptionsUsePageSettingsFromWord property, which specifies whether to use the page settings from the Word document or custom values defined in code. An object of type WordToPdfDocumentOptions is exposed through the WordToPdfConverterPdfDocumentOptions property.

If UsePageSettingsFromWord is set to true, the converter will use the page size, orientation and margins defined in the Word document. The following example demonstrates how to enable this behavior.

Use Page Settings from Word
wordToPdfConverter.PdfDocumentOptions.UsePageSettingsFromWord = true;

If UsePageSettingsFromWord is set to false, the converter will use the custom PDF page settings defined through the WordToPdfConverterPdfDocumentOptions property. The following example shows how to configure custom page size, orientation and margins.

Use Custom PDF Page Settings
wordToPdfConverter.PdfDocumentOptions.UsePageSettingsFromWord = false;
wordToPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
wordToPdfConverter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Landscape;
wordToPdfConverter.PdfDocumentOptions.LeftMargin = 20;
wordToPdfConverter.PdfDocumentOptions.RightMargin = 20;
wordToPdfConverter.PdfDocumentOptions.TopMargin = 30;
wordToPdfConverter.PdfDocumentOptions.BottomMargin = 30;

Add HTML Headers and Footers

You can add a header or footer from a URL or from an HTML string. The header and footer can include variables such as {page_number} or {total_pages} and support automatic resizing.

The creation of the HTML header and footer is controlled by the WordToPdfDocumentOptionsPdfHtmlHeader and WordToPdfDocumentOptionsPdfHtmlFooter properties. These properties expose objects of type PdfHtmlHeaderFooter, which derives from PdfHtmlTemplate.

The WordToPdfDocumentOptions object is exposed through the WordToPdfConverterPdfDocumentOptions property.

The header and footer options are similar to those available in the HTML to PDF Converter and are described in detail in the HTML Header and Footer with Page Numbers documentation section.

Page Break Recognition

The WordToPdfConverterProcessPageBreakMarks property controls whether page break markers found in the Word document are translated into actual page breaks in the generated PDF. The default value is true, which means that page breaks defined in the Word content will be preserved during conversion.

Enable Page Breaks from Word Document
wordToPdfConverter.ProcessPageBreakMarks = true;

Save PDF Output

After conversion, the resulting PDF document can be returned as a byte array for in-memory processing, such as streaming to a web client or saving to a database. Alternatively, you can write the byte array to disk to store the PDF as a file.

Save PDF to Memory
byte[] outPdfBuffer = wordToPdfConverter.ConvertToPdf(wordBytes);
Save PDF to File
File.WriteAllBytes("output.pdf", outPdfBuffer);

Code Sample - Convert Word to PDF

Convert Word to PDF in ASP.NET Core
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

using HiQPdf.Chromium;

namespace HiQPdf_Chromium_AspNetDemo.Controllers
{
    public class Word_to_PDFController : Controller
    {
        private readonly IWebHostEnvironment m_hostingEnvironment;

        public Word_to_PDFController(IWebHostEnvironment hostingEnvironment)
        {
            m_hostingEnvironment = hostingEnvironment;
        }

        public IActionResult Index()
        {
            SetCurrentViewData();

            return View();
        }

        [HttpPost]
        public async Task<IActionResult> ConvertWordToPdf(IFormCollection collection)
        {
            // Replace the demo serial number with the serial number received upon purchase
            // to run the converter in licensed mode
            Licensing.SerialNumber = "YCgJMTAE-BiwJAhIB-EhlWTlBA-UEBRQFBA-U1FOUVJO-WVlZWQ==";

            // Create a Word to PDF converter object with default settings
            WordToPdfConverter wordToPdfConverter = new WordToPdfConverter();

            //  Set whether to use page settings (size, margins) from the Word document or the custom settings
            wordToPdfConverter.PdfDocumentOptions.UsePageSettingsFromWord = collection["PdfPageSettingsMode"] == "fromWordDocumentRadioButton";

            // Set whether page break marks from Word documents should be processed
            wordToPdfConverter.ProcessPageBreakMarks = collection["processWordPageBreakMarksCheckBox"].Count > 0;

            if (!wordToPdfConverter.PdfDocumentOptions.UsePageSettingsFromWord)
            {
                // Set PDF page size which can be a predefined size like A4 or a custom size in points 
                // Leave it not set to have a default A4 PDF page
                wordToPdfConverter.PdfDocumentOptions.PageSize = SelectedPdfPageSize(collection["pdfPageSizeDropDownList"]);

                // Set PDF page orientation to Portrait or Landscape
                // Leave it not set to have a default Portrait orientation for PDF page
                wordToPdfConverter.PdfDocumentOptions.PageOrientation = SelectedPdfPageOrientation(collection["pdfPageOrientationDropDownList"]);

                // Set PDF page margins in points or leave them not set to have a PDF page without margins
                wordToPdfConverter.PdfDocumentOptions.Margins.Left = int.Parse(collection["leftMarginTextBox"]);
                wordToPdfConverter.PdfDocumentOptions.Margins.Right = int.Parse(collection["rightMarginTextBox"]);
                wordToPdfConverter.PdfDocumentOptions.Margins.Top = int.Parse(collection["topMarginTextBox"]);
                wordToPdfConverter.PdfDocumentOptions.Margins.Bottom = int.Parse(collection["bottomMarginTextBox"]);

                // Set the Word viewer zoom percentage
                wordToPdfConverter.PdfDocumentOptions.Zoom = int.Parse(collection["wordViewerZoomTextBox"]);
            }

            // Set PDF header and footer
            SetHeader(wordToPdfConverter, collection);
            SetFooter(wordToPdfConverter, collection);

            // Get the Word document to convert
            string wordUrl = collection["wordFileUrlTextBox"][0].Trim();
            if (string.IsNullOrWhiteSpace(wordUrl))
                throw new Exception("No Word file to convert");

            byte[] inputWordfBytes;

            if (wordUrl.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
            {
                string localPath = new Uri(wordUrl).LocalPath;
                inputWordfBytes = await System.IO.File.ReadAllBytesAsync(localPath);
            }
            else
            {
                using var httpClient = new System.Net.Http.HttpClient();
                inputWordfBytes = await httpClient.GetByteArrayAsync(wordUrl);
            }

            // The buffer to receive the generated PDF document
            byte[] outPdfBuffer = wordToPdfConverter.ConvertToPdf(inputWordfBytes);

            // Send the PDF file to browser
            FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
            // send as attachment
            fileResult.FileDownloadName = "Word_to_Pdf.pdf";

            return fileResult;
        }

        private void SetHeader(WordToPdfConverter wordToPdfConverter, IFormCollection collection)
        {
            bool headerEnabled = collection["headerEnabledCheckBox"].Count > 0;
            if (!headerEnabled)
                return;

            // Set the header HTML from a URL or from an HTML string
            bool headerHtmlFromUrl = collection["HeaderHtmlSource"] == "headerUrlRadioButton";
            if (headerHtmlFromUrl)
            {
                string headerUrl = collection["headerUrlTextBox"];

                wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.HtmlSourceUrl = headerUrl;
            }
            else
            {
                string headerHtml = collection["headerHtmlTextBox"];
                string headerHtmlBaseUrl = collection["headerHtmlBaseUrlTextBox"];

                wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.Html = headerHtml;
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.HtmlBaseUrl = headerHtmlBaseUrl;
            }

            // Enable automatic height adjustment based on header HTML content
            bool autoSizeHeaderContentHeight = collection["autoSizeHeaderContentHeightCheckBox"].Count > 0;
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.AutoSizeContentHeight = autoSizeHeaderContentHeight;

            // Set the minimum and maximum content height used when AutoSizeContentHeight is enabled
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.MinContentHeight = int.Parse(collection["headerMinContentHeightTextBox"]);
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.MaxContentHeight = int.Parse(collection["headerMaxContentHeightTextBox"]);

            // Set a fixed height for the header if AutoResizeHeight is disabled
            string headerHeightValueString = collection["headerHeightTextBox"];
            if (!string.IsNullOrEmpty(headerHeightValueString))
            {
                int headerHeight = int.Parse(headerHeightValueString);
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.Height = headerHeight;
            }

            // If AutoResizeHeight is enabled and both Height and FitHeight are set,
            // the content may be scaled down to fit the specified height
            bool fitHeaderHeight = collection["fitHeaderHeightCheckBox"].Count > 0;
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.FitHeight = fitHeaderHeight;

            // Enable automatic top margin adjustment in the PDF based on the header
            bool autoResizeTopMargin = collection["autoResizeTopMarginCheckBox"].Count > 0;
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.AutoResizePdfMargins = autoResizeTopMargin;

            // Set header visibility on specific PDF pages: first page, odd-numbered pages and even-numbered pages
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.ShowInFirstPage = collection["showHeaderInFirstPageCheckBox"].Count > 0;
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.ShowInOddPages = collection["showHeaderInOddPagesCheckBox"].Count > 0;
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.ShowInEvenPages = collection["showHeaderInEvenPagesCheckBox"].Count > 0;

            // Reserve space for the header on all pages, regardless of visibility
            // If false, the document will be rendered using print styles instead of screen styles
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.ReserveSpaceAlways = collection["reserveHeaderSpaceCheckBox"].Count > 0;

            // Optimize the header rendering time by providing a hint if the HTML template contains variables such as { page_number} or { total_pages}
            wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.SkipVariablesParsing = collection["skipHeaderVariablesParsingCheckBox"].Count > 0;

            // Optionally set additional time to wait for the asynchronous header HTML content before rendering
            if (collection["headerWaitBeforeConvertTextBox"][0].Length > 0)
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlHeader.WaitBeforeConvert = int.Parse(collection["headerWaitBeforeConvertTextBox"]);
        }

        private void SetFooter(WordToPdfConverter wordToPdfConverter, IFormCollection collection)
        {
            bool footerEnabled = collection["footerEnabledCheckBox"].Count > 0;
            if (footerEnabled)
            {
                // Set the footer HTML from a URL or from an HTML string
                bool footerHtmlFromUrl = collection["FooterHtmlSource"] == "footerUrlRadioButton";
                if (footerHtmlFromUrl)
                {
                    string footerUrl = collection["footerUrlTextBox"];

                    wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.HtmlSourceUrl = footerUrl;
                }
                else
                {
                    string footerHtml = collection["footerHtmlTextBox"];
                    string footerHtmlBaseUrl = collection["footerHtmlBaseUrlTextBox"];

                    wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.Html = footerHtml;
                    wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.HtmlBaseUrl = footerHtmlBaseUrl;
                }

                // Enable automatic height adjustment based on footer HTML content
                bool autoSizeFooterContentHeight = collection["autoSizeFooterContentHeightCheckBox"].Count > 0;
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.AutoSizeContentHeight = autoSizeFooterContentHeight;

                // Set the minimum and maximum content height used when AutoSizeContentHeight is enabled
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.MinContentHeight = int.Parse(collection["footerMinContentHeightTextBox"]);
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.MaxContentHeight = int.Parse(collection["footerMaxContentHeightTextBox"]);

                // Set a fixed height for the footer if AutoResizeHeight is disabled
                string footerHeightValueString = collection["footerHeightTextBox"];
                if (!string.IsNullOrEmpty(footerHeightValueString))
                {
                    int footerHeight = int.Parse(footerHeightValueString);
                    wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.Height = footerHeight;
                }

                // If AutoResizeHeight is enabled and both Height and FitHeight are set,
                // the content may be scaled down to fit the specified height
                bool fitFooterHeight = collection["fitFooterHeightCheckBox"].Count > 0;
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.FitHeight = fitFooterHeight;

                // Enable automatic bottom margin adjustment in the PDF based on the footer
                bool autoResizeBottomMargin = collection["autoResizeBottomMarginCheckBox"].Count > 0;
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.AutoResizePdfMargins = autoResizeBottomMargin;

                // Set footer visibility on specific PDF pages: first page, odd-numbered pages and even-numbered pages
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.ShowInFirstPage = collection["showFooterInFirstPageCheckBox"].Count > 0;
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.ShowInOddPages = collection["showFooterInOddPagesCheckBox"].Count > 0;
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.ShowInEvenPages = collection["showFooterInEvenPagesCheckBox"].Count > 0;

                // Reserve space for the footer on all pages, regardless of visibility
                // If false, the document will be rendered using print styles instead of screen styles
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.ReserveSpaceAlways = collection["reserveFooterSpaceCheckBox"].Count > 0;

                // Optimize the footer rendering time by providing a hint if the HTML template contains variables such as { page_number} or { total_pages}
                wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.SkipVariablesParsing = collection["skipFooterVariablesParsingCheckBox"].Count > 0;

                // Optionally set additional time to wait for the asynchronous footer HTML content before rendering
                if (collection["footerWaitBeforeConvertTextBox"][0].Length > 0)
                    wordToPdfConverter.PdfDocumentOptions.PdfHtmlFooter.WaitBeforeConvert = int.Parse(collection["footerWaitBeforeConvertTextBox"]);
            }
        }

        private PdfPageSize SelectedPdfPageSize(string selectedValue)
        {
            switch (selectedValue)
            {
                case "A0":
                    return PdfPageSize.A0;
                case "A1":
                    return PdfPageSize.A1;
                case "A10":
                    return PdfPageSize.A10;
                case "A2":
                    return PdfPageSize.A2;
                case "A3":
                    return PdfPageSize.A3;
                case "A4":
                    return PdfPageSize.A4;
                case "A5":
                    return PdfPageSize.A5;
                case "A6":
                    return PdfPageSize.A6;
                case "A7":
                    return PdfPageSize.A7;
                case "A8":
                    return PdfPageSize.A8;
                case "A9":
                    return PdfPageSize.A9;
                case "ArchA":
                    return PdfPageSize.ArchA;
                case "ArchB":
                    return PdfPageSize.ArchB;
                case "ArchC":
                    return PdfPageSize.ArchC;
                case "ArchD":
                    return PdfPageSize.ArchD;
                case "ArchE":
                    return PdfPageSize.ArchE;
                case "B0":
                    return PdfPageSize.B0;
                case "B1":
                    return PdfPageSize.B1;
                case "B2":
                    return PdfPageSize.B2;
                case "B3":
                    return PdfPageSize.B3;
                case "B4":
                    return PdfPageSize.B4;
                case "B5":
                    return PdfPageSize.B5;
                case "Flsa":
                    return PdfPageSize.Flsa;
                case "HalfLetter":
                    return PdfPageSize.HalfLetter;
                case "Ledger":
                    return PdfPageSize.Ledger;
                case "Legal":
                    return PdfPageSize.Legal;
                case "Letter":
                    return PdfPageSize.Letter;
                case "Letter11x17":
                    return PdfPageSize.Letter11x17;
                case "Note":
                    return PdfPageSize.Note;
                default:
                    return PdfPageSize.A4;
            }
        }

        private PdfPageOrientation SelectedPdfPageOrientation(string selectedValue)
        {
            return selectedValue == "Portrait" ? PdfPageOrientation.Portrait : PdfPageOrientation.Landscape;
        }

        private void SetCurrentViewData()
        {
            ViewData["ContentRootPath"] = m_hostingEnvironment.ContentRootPath + "/wwwroot";

            HttpRequest request = ControllerContext.HttpContext.Request;
            UriBuilder uriBuilder = new UriBuilder();
            uriBuilder.Scheme = request.Scheme;
            uriBuilder.Host = request.Host.Host;
            if (request.Host.Port != null)
                uriBuilder.Port = (int)request.Host.Port;
            uriBuilder.Path = request.PathBase.ToString() + request.Path.ToString();
            uriBuilder.Query = request.QueryString.ToString();

            ViewData["CurrentPageUrl"] = uriBuilder.Uri.AbsoluteUri;
        }
    }
}

See Also