Merge Multiple HTML to PDF

Winnovative PDF Chromium can convert multiple HTML documents to a single PDF using the Winnovative.Pdf.ChromiumPdfMerge class. Each HTML is converted to PDF and the result is added to PdfMerge using the PdfMergeAddPdf(Byte, String) method. The PdfMerge class allows you to set security options, configure PDF viewer preferences and apply a digital signature to the resulting PDF.

Code Sample - Merge Multiple HTML to PDF

C#
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

// Use Winnovative Namespace
using Winnovative.Pdf.Chromium;

namespace Winnovative_Chromium_AspNetDemo.Controllers.HTML_to_PDF
{
    public class Merge_Multiple_HTML_to_PDFController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult MergePdf(IFormCollection collection)
        {
            // Set license key received after purchase to use the converter in licensed mode
            // Leave it not set to use the library in demo mode
            Licensing.LicenseKey = "fvDh8eDx4fHg4P/h8eLg/+Dj/+jo6Og=";

            // Create PDF merger
            using PdfMerge pdfMerge = new PdfMerge();

            // Set PDF merge options
            SetPdfMergeOptions(pdfMerge, collection);

            // Create the list of URLs to convert
            List<string> urlsToConvert = new List<string>() {
                collection["firstUrlTextBox"],
                collection["secondUrlTextBox"]
            };

            foreach (string url in urlsToConvert)
            {
                // Create the HTML to PDF Converter
                HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

                // Set the HTML to PDF Converter options
                SetHtmlToPdfConverterOptions(htmlToPdfConverter, collection);

                if (collection["generateTocCheckBox"].Count > 0)
                {
                    // adjust second TOC page numbers with the number of PDF pages generated by previous conversions
                    htmlToPdfConverter.PdfDocumentOptions.TableOfContents.PageNumbersOffset = pdfMerge.PdfMergeInfo.TotalPagesProduced;
                }

                // Convert HTML to PDF
                byte[] pdfBytes = htmlToPdfConverter.ConvertUrl(url);

                // Add the PDF to the merger
                int firstPdfPageCount = pdfMerge.AddPdf(pdfBytes);
            }

            // Merge the PDF documents
            byte[] mergedPdf = pdfMerge.Save();

            // Send the merged PDF file to browser
            FileResult fileResult = new FileContentResult(mergedPdf, "application/pdf");
            fileResult.FileDownloadName = "Merge_Multipe_HTML.pdf";

            return fileResult;
        }

        private void SetHtmlToPdfConverterOptions(HtmlToPdfConverter htmlToPdfConverter, IFormCollection collection)
        {
            // Set HTML Viewer width in pixels which is the equivalent in converter of the browser window width
            htmlToPdfConverter.HtmlViewerWidth = int.Parse(collection["htmlViewerWidthTextBox"]);

            // Set the initial HTML viewer height in pixels
            if (collection["htmlViewerHeightTextBox"][0].Length > 0)
                htmlToPdfConverter.HtmlViewerHeight = int.Parse(collection["htmlViewerHeightTextBox"]);

            // Set the HTML content zoom percentage similar to zoom level in a browser
            htmlToPdfConverter.HtmlViewerZoom = int.Parse(collection["htmlViewerZoomTextBox"]);

            // 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
            htmlToPdfConverter.PdfDocumentOptions.PdfPageSize = SelectedPdfPageSize(collection["pdfPageSizeDropDownList"]);

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

            // optionally auto resize PDF page width to HTML viewer width
            htmlToPdfConverter.PdfDocumentOptions.AutoResizePdfPageWidth = collection["autoResizePdfPageWidthCheckBox"].Count > 0;

            // Set PDF page margins in points or leave them not set to have a PDF page without margins
            htmlToPdfConverter.PdfDocumentOptions.LeftMargin = int.Parse(collection["leftMarginTextBox"]);
            htmlToPdfConverter.PdfDocumentOptions.RightMargin = int.Parse(collection["rightMarginTextBox"]);
            htmlToPdfConverter.PdfDocumentOptions.TopMargin = int.Parse(collection["topMarginTextBox"]);
            htmlToPdfConverter.PdfDocumentOptions.BottomMargin = int.Parse(collection["bottomMarginTextBox"]);

            // Enable the creation of a hierarchy of bookmarks from H1 to H6 tags
            htmlToPdfConverter.PdfDocumentOptions.GenerateDocumentOutline = collection["autoBookmarksCheckBox"].Count > 0;

            // Enable or disable the automatic creation of a table of contents in the PDF document based on H1 to H6 HTML tags
            htmlToPdfConverter.PdfDocumentOptions.GenerateTableOfContents = collection["generateTocCheckBox"].Count > 0;

            // Set the maximum time in seconds to wait for HTML page to be loaded 
            // Leave it not set for a default 120 seconds maximum wait time
            htmlToPdfConverter.NavigationTimeout = int.Parse(collection["navigationTimeoutTextBox"]);

            // Set an adddional delay in seconds to wait for JavaScript or AJAX calls after page load completed
            // Set this property to 0 if you don't need to wait for such asynchcronous operations to finish
            if (collection["conversionDelayTextBox"][0].Length > 0)
                htmlToPdfConverter.ConversionDelay = int.Parse(collection["conversionDelayTextBox"]);
        }

        private void SetPdfMergeOptions(PdfMerge pdfMerge, IFormCollection collection)
        {
            // Set the encryption algorithm and the encryption key size if they are not the default ones
            if (collection["EncryptionKey"] != "bit128RadioButton" || collection["EncryptionType"] != "rc4RadioButton")
            {
                // set the encryption algorithm
                pdfMerge.PdfSecurityOptions.EncryptionAlgorithm = collection["EncryptionType"] == "rc4RadioButton" ? EncryptionAlgorithm.RC4 : EncryptionAlgorithm.AES;

                // set the encryption key size
                if (collection["EncryptionKey"] == "bit40RadioButton")
                    pdfMerge.PdfSecurityOptions.KeySize = EncryptionKeySize.EncryptKey40Bit;
                else if (collection["EncryptionKey"] == "bit128RadioButton")
                    pdfMerge.PdfSecurityOptions.KeySize = EncryptionKeySize.EncryptKey128Bit;
                else if (collection["EncryptionKey"] == "bit256RadioButton")
                    pdfMerge.PdfSecurityOptions.KeySize = EncryptionKeySize.EncryptKey256Bit;
            }

            // Set user and owner passwords
            if (collection["userPasswordTextBox"][0].Length > 0)
                pdfMerge.PdfSecurityOptions.UserPassword = collection["userPasswordTextBox"];

            if (collection["ownerPasswordTextBox"][0].Length > 0)
                pdfMerge.PdfSecurityOptions.OwnerPassword = collection["ownerPasswordTextBox"];

            // Set PDF document permissions
            pdfMerge.PdfSecurityOptions.CanPrint = collection["printEnabledCheckBox"].Count > 0;
            pdfMerge.PdfSecurityOptions.CanCopyContent = collection["copyContentEnabledCheckBox"].Count > 0;
            pdfMerge.PdfSecurityOptions.CanCopyAccessibilityContent = collection["copyAccessibilityContentEnabledCheckBox"].Count > 0;
            pdfMerge.PdfSecurityOptions.CanEditContent = collection["editContentEnabledCheckBox"].Count > 0;
            pdfMerge.PdfSecurityOptions.CanEditAnnotations = collection["editAnnotationsEnabledCheckBox"].Count > 0;
            pdfMerge.PdfSecurityOptions.CanFillFormFields = collection["fillFormFieldsEnabledCheckBox"].Count > 0;

            if ((PermissionsChanged(pdfMerge) || pdfMerge.PdfSecurityOptions.UserPassword.Length > 0) &&
                pdfMerge.PdfSecurityOptions.OwnerPassword.Length == 0)
            {
                // A user password is set but the owner password is not set or the permissions are not the default ones
                // Set a default owner password
                pdfMerge.PdfSecurityOptions.OwnerPassword = "owner";
            }
        }

        private bool PermissionsChanged(PdfMerge pdfMerge)
        {
            return !pdfMerge.PdfSecurityOptions.CanPrint ||
                    !pdfMerge.PdfSecurityOptions.CanCopyContent || !pdfMerge.PdfSecurityOptions.CanCopyAccessibilityContent ||
                    !pdfMerge.PdfSecurityOptions.CanEditContent || !pdfMerge.PdfSecurityOptions.CanEditAnnotations ||
                    !pdfMerge.PdfSecurityOptions.CanFillFormFields;
        }

        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;
        }
    }
}

See Also