Render and print PDF documents in C# and VB.NET
Everybody thinks about Adobe Reader when it comes to reading PDF documents. But what to do if you are a software developer and want to display PDF documents in your application? You do not want to ask the user to set up Adobe Reader and open the document there.
You may also need to implement other PDF-related requirements. For example, print PDF documents. Or generate thumbnails for uploaded PDF documents. Or support PDF editing in your desktop or web application.
All you need is a PDF library that can render and print PDF documents.
.NET library to view, edit, or print PDF documents
Docotic.Pdf library allows you to display, edit, and print PDF documents in C# and VB.NET. You can implement any complex PDF rendering flow using three core features.
The first one is the ability to convert PDF to images. You can implement almost everything based on this feature. From PDF printing to displaying a PDF on HoloLense or posting a PDF on Instagram. That is possible because images are supported everywhere.
The second key feature is the ability to draw PDF pages on the drawing surface of a
System.Drawing.Graphics
. It allows you to render and print PDFs in Windows Forms or WPF
applications. To use this feature, add BitMiracle.Docotic.Pdf.Gdi extension
DLL to your project.
Last but not least is the ability to extract PDF page objects. This feature allows you to build PDF viewer or PDF editor in your C# or VB.NET application.
9.5.17615-dev 14,813 passed Total NuGet downloads 4,924,084Get the library and a free time-limited license key on the Download C# .NET PDF library page.
Print PDF in Windows Forms or WPF application
.NET does not support printing of PDF documents out of the box. You need to transform your PDF
document to an image, an XPS file, or draw it to a System.Drawing.Graphics
surface. Then you can
use .NET classes to print the output from within a Windows Forms or a WPF application.
In Windows Forms applications, you can use classes from System.Drawing.Printing
namespace. There
are also handy PrintDialog
and PrintPreviewDialog
classes for building printing UI.
Please note that it is not recommended to use anything from the System.Drawing
namespace in macOS
and Linux environments. The macOS and Linux implementations of the System.Drawing
are incomplete
and different from the Windows implementation. You might get incorrect and/or inconsistent results
if you use the System.Drawing
namespace in macOS and Linux environments.
WPF provides another PrintDialog
class but does not provide classes for print preview. Luckily,
WPF allows you to use PrintPreviewDialog
class from System.Windows.Forms.dll. Thus, it's easier
to use print classes from System.Windows.Forms
and System.Drawing.Printing
namespaces in WPF
applications.
Look at the Print PDF in .NET demo application that comes in C# and VB.NET versions for WinForms and WPF. The application shows how to:
- display a print preview for PDF documents
- print PDF documents to a selected printer
- set up the paper size, the scaling mode, and other print settings
The application uses Docotic.Pdf library, BitMiracle.Docotic.Pdf.Gdi extension
DLL, and print classes from System.Windows.Forms
and
System.Drawing.Printing
namespaces. You can use its PdfPrintDocument
and PdfPrintHelper classes in your WPF or Windows Forms projects.
The PdfPrintDocument
class describes the main printing logic. This class connects Docotic.Pdf
with the System.Drawing.Printing.PrintDocument
class. The key method is the
printDocument_PrintPage
event handler:
private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics gr = e.Graphics;
// Work in points to have consistent units for all contexts:
// 1. Printer
// 2. Print preview
// 3. PDF
gr.PageUnit = GraphicsUnit.Point;
if (m_printAction == PrintAction.PrintToPreview)
{
gr.Clear(Color.LightGray);
gr.FillRectangle(Brushes.White, m_printableAreaInPoints);
gr.IntersectClip(m_printableAreaInPoints);
gr.TranslateTransform(m_printableAreaInPoints.X, m_printableAreaInPoints.Y);
}
PdfPage page = m_pdf.Pages[m_pageIndex];
PdfSize pageSizeInPoints = getPageSizeInPoints(page);
if (m_printSize == PrintSize.FitPage)
{
float sx = (float)(m_printableAreaInPoints.Width / pageSizeInPoints.Width);
float sy = (float)(m_printableAreaInPoints.Height / pageSizeInPoints.Height);
float scaleFactor = Math.Min(sx, sy);
centerContentInPrintableArea(gr, pageSizeInPoints, scaleFactor);
gr.ScaleTransform(scaleFactor, scaleFactor);
}
else if (m_printSize == PrintSize.ActualSize)
{
centerContentInPrintableArea(gr, pageSizeInPoints, 1);
}
page.Draw(gr);
++m_pageIndex;
e.HasMorePages = (m_pageIndex <= m_lastPageIndex);
}
First, we set up transformations of the printed page's Graphics
object. It's important to respect
the "Fit page" and "Actual size" settings. And we also display the printer's hard margins in the
Print Preview dialog. Then we draw the current PDF page on the Graphics
object using
PdfPage.Draw extension method.
The PdfPrintHelper
class allows you to use PdfPrintDocument
with UI classes for printing. For
example, you can show the print dialog for your PDF document like that:
using (var pdf = new PdfDocument("your_document.pdf"))
action(pdf, getPrintSize());
public static DialogResult ShowPrintDialog(PdfDocument pdf, PrintSize printSize)
{
using (var printDialog = new PrintDialog())
{
printDialog.AllowSomePages = true;
printDialog.AllowCurrentPage = true;
printDialog.AllowSelection = true;
printDialog.PrinterSettings.MinimumPage = 1;
printDialog.PrinterSettings.MaximumPage = pdf.PageCount;
printDialog.PrinterSettings.FromPage = printDialog.PrinterSettings.MinimumPage;
printDialog.PrinterSettings.ToPage = printDialog.PrinterSettings.MaximumPage;
var result = printDialog.ShowDialog();
if (result == DialogResult.OK)
{
using (var printDocument = new PdfPrintDocument(pdf, printSize))
printDocument.Print(printDialog.PrinterSettings);
}
return result;
}
}
That's it. Do the following to implement PDF printing in your Windows Forms or WPF application:
- add
PdfPrintDocument
,PdfPrintHelper
, andPrintSize
files from the sample - add a reference to Docotic.Pdf library
- add a reference to BitMiracle.Docotic.Pdf.Gdi extension DLL
- (WPF only) add references to System.Windows.Forms and System.Drawing assemblies
Print PDF using conversion to image
Classes from System.Drawing.Printing
namespace work well in Windows Forms and WPF applications.
But, there are cases when you can't or shouldn't use System.Drawing.Printing
.
For example, you should not use System.Drawing.Printing
in Windows services or ASP.NET
applications. System.Drawing.Printing
might produce inconsistent results when printing on Linux
or macOS. And you cannot use System.Drawing.Printing
in Eto.Forms or Avalonia applications.
In such cases, you need to convert PDF document to image first. This C# sample shows how to save a PDF page as a PNG image or convert an entire PDF document to a multipage TIFF:
using (var pdf = new PdfDocument(@"your_document.pdf"))
{
PdfDrawOptions options = PdfDrawOptions.Create();
options.HorizontalResolution = printerDpi;
options.VerticalResolution = printerDpi;
// save one page
pdf.Pages[0].Save("page0.png", options);
// save the whole document as multipage bitonal TIFF
options.Compression = ImageCompressionOptions.CreateTiff().SetBitonal();
pdf.SaveAsTiff("your_document.tiff", options);
}
Then, print images using an alternative printing framework or tool. Look at the Print PDF in
Eto.Forms demo application that shows how to print PDF documents without
System.Drawing.Printing
.
Render PDF in C# and VB.NET
Displaying of PDF in your application is like printing. In ASP.NET, WPF, Eto.Forms, Avalonia, or any other application type, convert PDF to image and then display the image.
In a Windows Forms app, you can draw a PDF page on a System.Drawing.Graphics
context from any
control. Or you can convert a PDF page to a System.Drawing.Bitmap
and then display the bitmap in
a PictureBox
.
This sample shows how to convert PDF page to Bitmap
in C#:
using (var pdf = new PdfDocument("render.pdf"))
{
const float TargetResolution = 300;
PdfPage page = pdf.Pages[0];
double scaleFactor = TargetResolution / page.Resolution;
using (var bitmap = new Bitmap((int)(page.Width * scaleFactor), (int)(page.Height * scaleFactor)))
{
bitmap.SetResolution(TargetResolution, TargetResolution);
using (Graphics gr = Graphics.FromImage(bitmap))
page.Draw(gr);
bitmap.Save("result.png");
}
}
The above code requires you to add BitMiracle.Docotic.Pdf.Gdi extension DLL to your project.
Create PDF viewer or PDF editor in .NET application
Docotic.Pdf allows you to get detailed information about every object on a PDF page. You can extract text chunks, images, vector paths, form controls, and annotations from a PDF page.
Then in your application, you can render all the extracted objects. You can also implement the ability to select and edit the rendered objects.
Look at the Extract text, images, and paths from PDF sample. It shows
how to extract and draw page objects to System.Drawing.Graphics
context.
You can also extract text objects as vector paths. Use PdfPage.GetObjects(PdfObjectExtractionOptions) overload for that.
Conclusion
Use Docotic.Pdf library to display and print PDF documents in your .NET projects. Look at related C# and VB.NET samples:
Contact us if you have questions about PDF printing or rendering.
Related resources
- Convert PDF to image in C# and VB.NET article
- Render and print PDF samples