Create PDF Documents

You can create PDF documents programmatically by adding text, images and other types of elements. The generated PDF can be saved either in memory or as a file and can be further processed using the PdfEditor component. You can enhance the generated PDF by adding security features such as encryption, permissions or a digital signature, as well as custom headers and footers or visual elements like stamps and shapes.

A PDF document created from scratch is represented by the HiQPdf.NextPdfDocument class, which allows you to add various PDF elements using a simple interface. For example, it provides the PdfDocumentAddText(PdfTextElement) method to add a text element to the current page of the document, or the PdfDocumentAddImage(PdfImageElement) method to add an image element to the current page of the PDF.

Create, Render Elements and Save PDF Documents

A PdfDocument can be created with the default options using the PdfDocument parameterless constructor. This creates a PDF document with an A4 portrait page size and no margins. The constructor also adds an empty page to the PDF document.

Create a PDF Document with Default Settings
// Create a new PDF document with the default settings
using PdfDocument pdfDocument = new PdfDocument();

To create a PDF document with a custom page size, orientation and margins, use the PdfDocument(PdfDocumentCreateSettings) constructor, which accepts a HiQPdf.NextPdfDocumentCreateSettings parameter where you can specify these options. The example below demonstrates how to create a PDF document with custom settings.

Create a PDF Document with Custom Settings
PdfDocumentCreateSettings pdfCreateSettings = new PdfDocumentCreateSettings()
{
  PageSize = PdfPageSize.A4,
  PageOrientation = PdfPageOrientation.Portrait,
  Margins = new PdfMargins(36, 36, 36, 36)
};

// Create a new PDF document with the specified settings
using PdfDocument pdfDocument = new PdfDocument(pdfCreateSettings);

Add New PDF Pages

The PdfDocument constructor automatically adds the first page to the document, where you can begin adding elements.

You can add new PDF pages using the PdfDocumentAddPage method. The new page uses the current page size, orientation and margins defined when the document was created. The example below shows how to add a new page using the current settings.

Add a New PDF Page
// Add a new PDF page with current settings
pdfDocument.AddPage();

You can change the page settings before adding a new page by using the PdfDocumentSetPageSize(PdfPageSize, PdfPageOrientation) method and the PdfDocumentMargins property. The example below adds an A4 landscape page with all margins set to 100 points.

Add a New PDF Page with Updated Settings
// Set the next page to landscape A4
pdfDocument.SetPageSize(PdfPageSize.A4, PdfPageOrientation.Landscape);

// Set the next page margins
pdfDocument.Margins = new PdfMargins(100, 100, 100, 100);

// Add a new PDF page with the modified page settings
pdfDocument.AddPage();

Add PDF Elements to Document

After creating the document, you can start adding elements to it. The PdfDocument class provides dedicated methods such as PdfDocumentAddText(PdfTextElement) for adding a text element to the current page, and PdfDocumentAddImage(PdfImageElement) for adding an image element.

If the PDF page has margins set, they are automatically taken into account when rendering elements. Each element is positioned or resized accordingly, to fit within the defined margins.

Save the PDF Document

After adding the desired elements to the PDF document, you can save the document to a file using the PdfDocumentSaveToFile(String) method. This method writes the PDF content to the specified file path on disk.

Save the PDF Document to a File
string outputPath = Path.Combine(outputDir, "GeneratedDocument.pdf");

// Save the document to disk
pdfDocument.Save(outputPath);

Alternatively, you can save the document to a memory buffer using the PdfDocumentSave overload without parameters, which returns a byte array. This approach is useful when sending the PDF to a web client or saving it to a database.

Save the PDF Document to Memory
// Save the document to a memory buffer
byte[] pdfBytes = pdfDocument.Save();

Dispose the PdfDocument

The HiQPdf.NextPdfDocument class implements IDisposable and should be disposed after use to release allocated resources.

Calling the PdfDocumentSave method automatically disposes the document. After calling Save, the PdfDocument instance should no longer be used.

If you do not call Save, you must dispose the document manually, either by using a using block or by calling Dispose explicitly.

Save and Dispose Automatically
// Save will dispose the document automatically
byte[] buffer = pdfDocument.Save();
Manual Dispose
PdfDocument pdfDocument = new PdfDocument();
byte[] buffer = pdfDocument.Save();
pdfDocument.Dispose();

Code Sample - Create PDF Documents with Text and Images

C#
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

using HiQPdf.Next;

namespace HiQPdf_Next_AspNetDemo.Controllers
{
    public class CreatePdfDocumentsController : Controller
    {
        private readonly IWebHostEnvironment m_hostingEnvironment;

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

        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult CreatePdf(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==";

            PdfDocumentCreateSettings pdfCreateSettings = new PdfDocumentCreateSettings()
            {
                PageSize = PdfPageSize.A4,
                PageOrientation = PdfPageOrientation.Portrait,
                Margins = new PdfMargins(36, 36, 36, 36)
            };

            // Create a new PDF document with the specified settings
            using PdfDocument pdfDocument = new PdfDocument(pdfCreateSettings);

            const int startXPos = 0;
            const int startYPos = 0;
            const int ySeparator = 15;

            int currentPage = pdfDocument.PageNumber;
            int crtXPos = startXPos;
            int crtYPos = startYPos;

            // Create a standard Helvetica font
            PdfFont fontHelvetica = PdfFontManager.CreateStandardFont(PdfStandardFont.Helvetica, 16f,
                PdfFontStyle.Bold | PdfFontStyle.Underline, PdfColor.Black);

            // Add a title using the Helvetica font
            PdfTextElement pdfTitle1 = new PdfTextElement("Transparent PNG Image with Custom Width", fontHelvetica)
            {
                X = crtXPos,
                Y = crtYPos
            };
            PdfTextRenderInfo textRenderInfo = pdfDocument.AddText(pdfTitle1);

            // Update the Y position after rendering the title
            crtYPos = textRenderInfo.LastPageRectangle.Bounds.Bottom + ySeparator;

            string imagesPath = GetDemoImagesPath();

            // Add a transparent PNG image with custom width
            PdfImageElement pdfPngImage = new PdfImageElement(Path.Combine(imagesPath, "transparent.png"))
            {
                X = crtXPos,
                Y = crtYPos,
                Width = 150
            };
            PdfImageRenderInfo imageRenderInfo = pdfDocument.AddImage(pdfPngImage);

            crtYPos = imageRenderInfo.BoundingBox.Bottom + ySeparator;

            // Create a standard Courier font
            PdfFont fontCourier = PdfFontManager.CreateStandardFont(PdfStandardFont.Courier, 16f,
                PdfFontStyle.Bold | PdfFontStyle.Italic, PdfColor.Green);

            // Add a title for the JPEG image
            PdfTextElement pdfTitle2 = new PdfTextElement("JPEG Image with Custom Height", fontCourier)
            {
                X = crtXPos,
                Y = crtYPos
            };
            textRenderInfo = pdfDocument.AddText(pdfTitle2);

            crtYPos = textRenderInfo.LastPageRectangle.Bounds.Bottom + ySeparator;

            // Ensure there is enough vertical space on the current page for the image.
            // Add a new page and reset Y position if needed
            EnsureSpaceOnPage(ref crtYPos, 200, pdfDocument);

            // Add a JPEG image with custom height
            PdfImageElement pdfJpgImage = new PdfImageElement(Path.Combine(imagesPath, "image.jpg"))
            {
                X = crtXPos,
                Y = crtYPos,
                Height = 150
            };
            imageRenderInfo = pdfDocument.AddImage(pdfJpgImage);

            crtYPos = imageRenderInfo.BoundingBox.Bottom + ySeparator;

            string fontsPath = GetDemoFontsPath();
            string textsPath = GetDemoTextsPath();

            string alphabetFilePath = Path.Combine(textsPath, "Alphabet.txt");
            string alfabetString = System.IO.File.ReadAllText(alphabetFilePath);

            // Create a blue bold Courier font
            PdfFont fontCourier2 = PdfFontManager.CreateStandardFont(PdfStandardFont.Courier, 16f,
                PdfFontStyle.Bold, PdfColor.Blue);

            // Add a title for the Unicode text
            PdfTextElement pdfTitle3 = new PdfTextElement("Multi Page Unicode Text with Custom Font", fontCourier2)
            {
                Y = crtYPos,
                Alignment = PdfTextAlignment.Center
            };
            textRenderInfo = pdfDocument.AddText(pdfTitle3);

            crtYPos = textRenderInfo.LastPageRectangle.Bounds.Bottom + ySeparator;

            string dejaVuRegularFontFile = Path.Combine(fontsPath, "DejaVuSerif.ttf");

            // Create an Unicode TrueType font from file
            PdfFont trueTypeFont = PdfFontManager.CreateFont(dejaVuRegularFontFile, 16f,
                PdfFontStyle.Normal, PdfColor.Black);

            // Add long Unicode text using the TrueType font, allowing continuation on next pages
            PdfTextElement pdfText1 = new PdfTextElement(alfabetString, trueTypeFont)
            {
                X = crtXPos,
                Y = crtYPos,
                Alignment = PdfTextAlignment.Left,
                ContinueOnNextPage = true
            };

            // Draw a rectangle around rendered text in each page
            pdfText1.OnPageRendered = (pageNumber, boundingBox) =>
            {
                PdfRectangleElement border = new PdfRectangleElement(boundingBox.X, boundingBox.Y,
                    boundingBox.Width, boundingBox.Height + 5)
                {
                    BorderColor = PdfColor.Blue,
                };
                pdfDocument.AddRectangle(border);
            };

            textRenderInfo = pdfDocument.AddText(pdfText1);

            // Set the next page to landscape A4
            pdfDocument.SetPageSize(PdfPageSize.A4, PdfPageOrientation.Landscape);

            // Add a new page
            pdfDocument.AddPage();

            // Reset positions
            crtXPos = 0;
            crtYPos = 0;

            // Add the same text again, with the same font, centered
            PdfTextElement pdfText2 = new PdfTextElement(alfabetString, trueTypeFont)
            {
                X = crtXPos,
                Y = crtYPos,
                Alignment = PdfTextAlignment.Center,
                ContinueOnNextPage = true
            };

            pdfText2.OnPageRendered = (pageNumber, boundingBox) =>
            {
                PdfRectangleElement border = new PdfRectangleElement(boundingBox.X, boundingBox.Y,
                    boundingBox.Width, boundingBox.Height + 5)
                {
                    BorderColor = PdfColor.Purple,
                };
                pdfDocument.AddRectangle(border);
            };

            textRenderInfo = pdfDocument.AddText(pdfText2);

            // Add a new page
            pdfDocument.AddPage();

            // Reset positions
            crtXPos = 0;
            crtYPos = 0;

            PdfFont rtlTileFont = PdfFontManager.CreateStandardFont(PdfStandardFont.Courier, 16f, 
                PdfFontStyle.Normal, PdfColor.Purple);

            PdfTextElement rtlTitle = new PdfTextElement("Add Right to Left Text", rtlTileFont)
            {
                X = crtXPos,
                Y = crtYPos
            };
            textRenderInfo = pdfDocument.AddText(rtlTitle);
            crtYPos = textRenderInfo.LastPageRectangle.Bounds.Bottom + ySeparator;

            // Create a Unicode font that supports Arabic (RTL)
            string notoSansArabicRegularFontFile = Path.Combine(fontsPath, "NotoSansArabic-Regular.ttf");

            PdfFont trueTypeFontArabic = PdfFontManager.CreateFont(notoSansArabicRegularFontFile, 16f,
                PdfFontStyle.Normal, PdfColor.Black);

            string rtlFilePath = Path.Combine(textsPath, "RightToLeft.txt");
            string rtlString = System.IO.File.ReadAllText(rtlFilePath);

            // Render the right to left text
            PdfTextElement pdfTextRtl = new PdfTextElement(rtlString, trueTypeFontArabic)
            {
                X = crtXPos,
                Y = crtYPos,
                Direction = PdfTextDirection.RightToLeft
            };
            textRenderInfo = pdfDocument.AddText(pdfTextRtl);

            // Save to memory buffer
            byte[] outPdfBuffer = pdfDocument.Save();

            // Send PDF to browser
            FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
            fileResult.FileDownloadName = "PdfDocument.pdf";

            return fileResult;
        }

        private void EnsureSpaceOnPage(ref int crtYPos, int requestedHeight, PdfDocument pdfDocument)
        {
            if (crtYPos + requestedHeight > pdfDocument.ContentHeight)
            {
                pdfDocument.AddPage();
                crtYPos = 0;
            }
        }

        private string GetDemoFilesPath()
        {
            return m_hostingEnvironment.ContentRootPath + "/wwwroot" + "/DemoFiles/";
        }

        private string GetDemoImagesPath()
        {
            return Path.Combine(GetDemoFilesPath(), "Images");
        }

        private string GetDemoFontsPath()
        {
            return Path.Combine(GetDemoFilesPath(), "Fonts");
        }

        private string GetDemoTextsPath()
        {
            return Path.Combine(GetDemoFilesPath(), "Text");
        }
    }
}

See Also