该页面可以包含自动翻译的文本。

在 C# 和 VB.NET 中渲染和打印 PDF 文档

说到阅读 PDF 文档,每个人都会想到 Adobe Reader。 但是,如果您是软件开发人员并且想要在应用程序中显示 PDF 文档该怎么办? 您不想要求用户设置 Adobe Reader 并在其中打开文档。

您可能还需要实现其他与 PDF 相关的要求。 例如,打印 PDF 文档。 或者为上传的 PDF 文档生成缩略图。 或 者支持在桌面或 Web 应用程序中编辑 PDF。

您所需要的只是一个可以渲染和打印 PDF 文档的 PDF 库。

在 C# 中打印 PDF

用于查看、编辑或打印 PDF 文档的 .NET 库

Docotic.Pdf 库 允许您在 C# 和 VB.NET 中显示、编辑和打印 PDF 文档。 您可以使用三 个核心功能来实现任何复杂的 PDF 渲染流程。

第一个是将 PDF 转换为图像 的功能。 您可以基于此功能实现几乎所有内容。 从 PDF 打印到在 HoloLense 上显示 PDF 或在 Instagram 上发布 PDF。 这是可能的,因为到处都支持图像。

第二个关键功能是能够在System.Drawing.Graphics的绘图表面上绘制 PDF 页面。 它允许您在 Windows 窗体 或 WPF 应用程序中渲染和打印 PDF。 要使用此功能,请将 BitMiracle.Docotic.Pdf.Gdi 扩展 DLL 添加到您的项目中。

最后但并非最不重要的是提取 PDF 页面对象的能力。 此功能允许您在 C# 或 VB.NET 应用程序中构建 PDF 查看 器或 PDF 编辑器。

Docotic.Pdf 库 9.3.17014-dev 回归测试 14,645 通过 NuGet 总下载量 4,172,488

您可以下载该库的二进制文件或使用其NuGet包。 要在没有评估 模式限制的情况下试用 Docotic.Pdf,您可以使用此处的表格 获取免费的限时 许可证密钥。

.NET 不支持直接打印 PDF 文档。 您需要将 PDF 文档转换为图像、XPS 文件,或将其绘制到 System.Drawing.Graphics表面。 然后,您可以使用 .NET 类从 Windows 窗体或 WPF 应用程序中打印输出。

在 Windows 窗体应用程序中,您可以使用System.Drawing.Printing命名空间中的类。 还有方便的 PrintDialogPrintPreviewDialog 类用于构建打印 UI。

请注意,不建议在 macOS 和 Linux 环境中使用System.Drawing命名空间中的任何内容。 System.Drawing 的 macOS 和 Linux 实现不完整并且与 Windows 实现不同。 如果您在 macOS 和 Linux 环境中使用 System.Drawing命名空间,您可能会得到不正确和/或不一致的结果。

WPF 提供了另一个 PrintDialog 类,但不提供用于打印预览的类。 幸运的是,WPF 允许您使用 System.Windows.Forms.dll 中的“PrintPreviewDialog”类。 因此,在 WPF 应用程序中使用 “System.Windows.Forms”和“System.Drawing.Printing”命名空间中的打印类会更容易。

查看 在 .NET 中打印 PDF 演示应用程序,该应用程序采用适用于 WinForms 和 WPF 的 C# 和 VB.NET 版本。 该应用程序展示了如何:

  • 显示 PDF 文档的打印预览
  • 将 PDF 文档打印到选定的打印机
  • 设置纸张尺寸、缩放模式和其他打印设置

该应用程序使用 Docotic.Pdf 库、BitMiracle.Docotic.Pdf.Gdi 扩展 DLL 以及来 自System.Windows.FormsSystem.Drawing.Printing命名空间的打印类 。 您可以在 WPF 或 Windows 窗体 项目中使用其 PdfPrintDocumentPdfPrintHelper 类。

PdfPrintDocument 类描述了主要的打印逻辑。 此类将 Docotic.Pdf 与 System.Drawing.Printing.PrintDocument类连接起来。 关键方法是 printDocument_PrintPage 事件处理程 序:

private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
    Graphics gr = e.Graphics;

    // 以点为单位进行工作,以便为所有上下文提供一致的单位:
    // 1. 打印机
    // 2. 打印预览
    // 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);
}

首先,我们设置打印页面的Graphics对象的转换。 尊重“适合页面”和“实际尺寸”设置非常重要。 我们还在“打 印预览”对话框中显示打印机的硬边距。 然后我们使用 PdfPage.Draw 扩展方法在 Graphics 对象上绘制当前 PDF 页面。

PdfPrintHelper 类允许您将 PdfPrintDocument 与 UI 类一起使用进行打印。 例如,您可以显示 PDF 文档 的打印对话框,如下所示:

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

就是这样。 执行以下操作以在 Windows 窗体或 WPF 应用程序中实现 PDF 打印:

  • 添加来自[示例]的 PdfPrintDocumentPdfPrintHelperPrintSize 文件(*pdf/PrintPdf)
  • 添加对 Docotic.Pdf 库的引用
  • 添加对 BitMiracle.Docotic.Pdf.Gdi 扩展 DLL 的引用 *(仅限 WPF)添加对 System.Windows.Forms 和 System.Drawing 程序集的引用

System.Drawing.Printing命名空间中的类在 Windows 窗体和 WPF 应用程序中运行良好。 但是,在某些情况 下您不能或不应该使用System.Drawing.Printing

例如,您不应在 Windows 服务或 ASP.NET 应用程序中使用System.Drawing.Printing。 在 Linux 或 macOS 上打印时,System.Drawing.Printing可能会产生不一致的结果。 并且您不能在 Eto.Forms 或 Avalonia 应用 程序中使用System.Drawing.Printing

在这种情况下,您需要先将PDF文档转换为图像。 此 C# 示例演示如何将 PDF 页面另存为 PNG 图像或将整个 PDF 文档转换为多页 TIFF:

using (var pdf = new PdfDocument(@"your_document.pdf"))
{
    PdfDrawOptions options = PdfDrawOptions.Create();
    options.HorizontalResolution = printerDpi;
    options.VerticalResolution = printerDpi;

    // 保存一页
    pdf.Pages[0].Save("page0.png", options);

    // 将整个文档另存为多页黑白 TIFF
    options.Compression = ImageCompressionOptions.CreateTiff().SetBitonal();
    pdf.SaveAsTiff("your_document.tiff", options);
}

然后,使用替代打印框架或工具打印图像。 查看 在 Eto.Forms 中打印 PDF 演示应 用程序,该应用程序展示了如何在没有System.Drawing.Printing的情况下打印 PDF 文档。

在 C# 和 VB.NET 中渲染 PDF

在应用程序中显示 PDF 就像打印一样。 在 ASP.NET、WPF、Eto.Forms、Avalonia 或任何其他应用程序类型 中,将 PDF 转换为图像,然后显示图像。

在 Windows 窗体应用程序中,您可以从任何控件的System.Drawing.Graphics上下文中绘制 PDF 页面。 或 者,您可以将 PDF 页面转换为System.Drawing.Bitmap,然后在PictureBox中显示该位图。

此示例展示了如何在 C# 中将 PDF 页面转换为Bitmap

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

上面的代码需要您将 BitMiracle.Docotic.Pdf.Gdi 扩展 DLL 添加到您的项目中。

在.NET应用程序中创建PDF查看器或PDF编辑器

Docotic.Pdf 允许您获取有关 PDF 页面上每个对象的详细信息。 您可以从 PDF 页面中提取文本块、图像、矢量 路径、表单控件和注释。

然后在您的应用程序中,您可以渲染所有提取的对象。 您还可以实现选择和编辑渲染对象的功能。

查看从 PDF 中提取文本、图像和路径 示例。 它展示了如何提取页面对象并将其 绘制到System.Drawing.Graphics上下文中。

您还可以将文本对象提取为矢量路径。 使用 PdfPage.GetObjects(PdfObjectExtractionOptions) 重载。

结论

使用 Docotic.Pdf 库 在 .NET 项目中显示和打印 PDF 文档。 查看相关的 C# 和 VB.NET 示例:

如果您对 PDF 打印或渲染有疑问,请联系我们