How to Create PDF Documents in ASP.NET Core
Tags: aspnet, aspdotnet, asp, pdf
Published: 2023-11-24 05:50:34

PDF generation is a common requirement for many web applications. ASP.NET Core provides several options for generating PDF documents directly from .NET code. In this article, we'll explore some of the main approaches for creating PDFs in ASP.NET Core apps.

We'll cover:

- Using built-in PDF generation support
- Third-party libraries like iTextSharp and PDFSharp
- Generating PDFs from HTML/CSS using libraries like PDFKit and Puppeteer Sharp
- Rendering to PDF on the server vs the client
- Sample code for a basic PDF generation scenario

By the end, you should have a good understanding of the different techniques available and how to get started generating PDFs from your ASP.NET Core applications.

## Built-in PDF Support
The .NET Framework and .NET Core provide some basic built-in functionality for generating PDF documents programmatically without a third-party dependency.

The System.Drawing namespace includes classes like PdfDocument and XGraphics that allow creating PDF files pixel-by-pixel. You can draw text, images, vectors, and more onto a PdfPage and save the result as a PDF file.

An example:

```csharp
// Create a new PdfDocument object
var pdfDoc = new PdfDocument(); 

// Add a page
pdfDoc.AddPage();

// Get an XGraphics object for drawing
var gfx = XGraphics.FromPdfPage(pdfDoc.Pages[0]);

// Draw text  
gfx.DrawString("Hello World!", font, XBrushes.Black, 0, 0);

// Save the document and dispose it
pdfDoc.Save("HelloWorld.pdf");
pdfDoc.Dispose();
```
This provides a basic building block but has limitations. Text/layout is rendered pixel-by-pixel so it may not scale or print well. There is also no support for things like vector graphics, tables, hyperlinks etc.

For richer PDF generation capabilities, third-party libraries are recommended.

## Third-Party Libraries
There are a number of high-quality third-party .NET libraries for generating sophisticated PDF documents from code:

#### iTextSharp
iTextSharp is one of the most full-featured and mature open source .NET PDF libraries available. It allows building PDF documents from scratch using elements like paragraphs, tables, images etc. Layout is handled separately from rendering so documents scale well.

An example:

```csharp
// Create a document and open it  
Document pdfDoc = new Document(PageSize.A4, 25, 25, 25, 25);
PdfWriter.GetInstance(pdfDoc, ms);
pdfDoc.Open(); 

// Add content
Paragraph p = new Paragraph("Hello World!");
pdfDoc.Add(p);

// Close the document
pdfDoc.Close();
```

#### PDFSharp
PDFSharp is another popular open source .NET library. It uses a page-oriented model and the drawing API is similar to GDI+. This makes it easy to render to PDF from existing GDI/GDI+ code.

An example:

```csharp
// Create a new PDF document
PdfDocument pdfDoc = new PdfDocument();

// Add a page
PdfPage page = pdfDoc.AddPage(); 

// Get drawing object and render
XGraphics gfx = XGraphics.FromPdfPage(page);
gfx.DrawString("Hello World!", font, XBrushes.Black, 0, 0);

// Save the document
pdfDoc.Save("HelloWorld.pdf");
```

#### wkhtmltopdf
wkhtmltopdf is a command line tool that renders HTML/CSS to PDF using the Webkit rendering engine. It can be used from .NET code by launching the process. This allows generating PDFs from dynamic HTML/CSS content.

```csharp
// Render HTML to a stream
var proc = new Process()
{
   StartInfo = new ProcessStartInfo
   {
      FileName = "wkhtmltopdf.exe", 
      Arguments = $"-q - -",
      RedirectStandardInput = true, 
      RedirectStandardOutput = true
   }
};

proc.Start();
proc.StandardInput.Write(html);
proc.StandardInput.Close();
proc.WaitForExit();

// Output stream contains PDF
pdf = proc.StandardOutput.BaseStream;
```
These are some of the most popular .NET PDF libraries. Each has its strengths - choose based on your specific requirements.

## Generating from HTML/CSS
Another common approach is to generate PDF from HTML/CSS content since it's easy to work with. There are a few options for doing this in .NET:

#### PDFKit
PDFKit is a .NET library that uses the HTML rendering engine WebKit to convert HTML + CSS to PDF documents.

```csharp
// Create a PDFKit document
var pdfDoc = new PdfDocument(); 

// Add a page and render HTML
var page = pdfDoc.AddPage();
page.Render(markup); 

// Save PDF
pdfDoc.Save("HelloWorld.pdf");
```

#### Puppeteer Sharp
Puppeteer Sharp is a .NET port of the Puppeteer Node.js library for controlling headless Chrome. It can render HTML to PDF using the Chromium rendering engine.

```csharp
var browser = await Puppeteer.LaunchAsync(options);
var page = await browser.NewPageAsync();

await page.GoToAsync(url);
await page.PdfAsync(output);

await browser.CloseAsync();
```

## HTML to PDF Converter
This library uses the HTML Rendering engine in .NET to convert HTML markup to PDF.

```csharp
var html = @"<h1>Hello World!</h1>";

var pdf = HtmlToPdfConverter.ConvertHtmlToPdf(html);

File.WriteAllBytes("HelloWorld.pdf", pdf);
```
Hence, these options allow rendering dynamic HTML/CSS content to high-fidelity PDF documents from .NET.

### Server vs Client Rendering
There are two main approaches for generating PDFs - on the server or client-side:

#### Server-Side

- Generate PDF directly from server code using a library
- Respond with generated PDF file
- Server handles all processing

**Pros:**
- Faster response for users
- No client-side dependencies
- Easier to implement

**Cons:**
- More load on server
- No interactivity

#### Client-Side
Return HTML/data needed to render PDF
Use client-side library like jsPDF to generate PDF in browser
User downloads/gets link to generated file
**Pros:**
- Reduces server load
- Allows for richer interactivity

**Cons:**
- Slower initial response
- Requires client-side code/libraries
So for simple static PDFs, server-side is better. For interactive/dynamic generation, consider a client-side approach.

**Example Project**
To put this into practice, here is a simple ASP.NET Core MVC sample project that generates a PDF on the server:

```csharp
// Controller action
public IActionResult GeneratePdf() 
{
   // Create document object
   Document pdfDoc = new Document(PageSize.A4, 25, 25, 25, 25);

   // Write content
   WriteParagraph(pdfDoc, "Hello World!");

   // Write to memory stream
   MemoryStream ms = new MemoryStream();
   PdfWriter.GetInstance(pdfDoc, ms);
   
   pdfDoc.Close();

   // Return generated PDF
   return File(ms.ToArray(), "application/pdf");
}

// Helper to add paragraph
private static void WriteParagraph(Document pdfDoc, string text)
{
   Paragraph p = new Paragraph(text);
   pdfDoc.Add(p);
}
```

**This demonstrates:**

- Creating a PDF using iTextSharp
- Adding simple content
- Writing PDF to a stream
- Returning PDF file result

With this approach, the server generates the PDF on request without any client-side processing required.

## Final Thoughts
In this article, we covered several techniques for programmatically generating PDF documents from ASP.NET Core applications. Whether you need a simple solution or full featured generation, .NET provides many high quality options.

The key aspects discussed were:

- Leveraging built-in .NET PDF support
- Popular third-party libraries like iTextSharp and PDFSharp
- Generating PDFs from HTML/CSS content
- Rendering on server vs client
- Sample code for a basic PDF generation scenario

With the right approach, ASP.NET Core makes developing PDF generation capabilities straightforward. Choose the technique that best fits your specific application requirements.