Эта страница может содержать автоматически переведенный текст.

Отрисовка и печать PDF-документов в C# и VB.NET

Когда речь идет о чтении PDF-документов, все думают об Adobe Reader. Но что делать, если вы разработчик и хотите отображать PDF-документы в своем приложении? Вы не хотите просить пользователя установить Adobe Reader и открыть документ там.

Вам также может понадобиться реализовать другие задачи, связанные с PDF. Например, печать PDF-документов. Или создание миниатюр для загруженных PDF-документов. Или поддержка редактирования PDF в вашем настольном или веб-приложении.

Все, что вам нужно, — это PDF-библиотека, которая может отрисовывать и печатать PDF-документы.

Печать PDF в C#

Библиотека .NET для просмотра, редактирования и печати PDF-документов

Библиотека Docotic.Pdf позволяет отображать, редактировать и печатать PDF-документы в C# и VB.NET. Вы можете реализовать любой сложный поток отрисовки PDF, используя три основные возможности.

Первая — это возможность преобразовывать PDF в изображения. На основе этой возможности можно реализовать практически все. От печати PDF до отображения PDF на HoloLens или публикации PDF в Instagram. Это возможно, потому что изображения поддерживаются везде.

Вторая ключевая возможность — отрисовка страниц PDF на поверхности рисования System.Drawing.Graphics. Она позволяет отрисовывать и печатать PDF в приложениях Windows Forms или WPF. Чтобы использовать эту возможность, добавьте в проект DLL расширения BitMiracle.Docotic.Pdf.Gdi.

И, наконец, возможность извлекать объекты страницы PDF. Эта возможность позволяет создать просмотрщик PDF или редактор PDF в вашем приложении C# или VB.NET.

Получите библиотеку и бесплатный лицензионный ключ с ограниченным сроком действия на странице Скачать C# .NET библиотеку PDF.

.NET не поддерживает печать PDF-документов из коробки. Вам нужно преобразовать PDF-документ в изображение, файл XPS или отрисовать его на поверхности System.Drawing.Graphics. Затем можно использовать классы .NET для печати результата из приложения Windows Forms или WPF.

В приложениях Windows Forms можно использовать классы из пространства имен System.Drawing.Printing. Также есть удобные классы PrintDialog и PrintPreviewDialog для создания интерфейса печати.

Обратите внимание: не рекомендуется использовать что-либо из пространства имен System.Drawing в средах macOS и Linux. Реализации System.Drawing для macOS и Linux неполные и отличаются от реализации для Windows. Если использовать пространство имен System.Drawing в macOS и Linux, можно получить некорректные и/или непоследовательные результаты.

WPF предоставляет другой класс PrintDialog, но не предоставляет классы для предварительного просмотра печати. К счастью, WPF позволяет использовать класс PrintPreviewDialog из System.Windows.Forms.dll. Поэтому в приложениях WPF проще использовать классы печати из пространств имен System.Windows.Forms и System.Drawing.Printing.

Посмотрите демонстрационное приложение Печать PDF в .NET, доступное в версиях для C# и VB.NET для WinForms и WPF. Приложение показывает, как:

  • отображать предварительный просмотр печати для PDF-документов
  • печатать PDF-документы на выбранный принтер
  • настраивать размер бумаги, режим масштабирования и другие параметры печати

Приложение использует библиотеку Docotic.Pdf, DLL расширения BitMiracle.Docotic.Pdf.Gdi и классы печати из пространств имен System.Windows.Forms и System.Drawing.Printing. Вы можете использовать его классы PdfPrintDocument и PdfPrintHelper в своих проектах WPF или Windows Forms.

Класс PdfPrintDocument описывает основную логику печати. Этот класс связывает Docotic.Pdf с классом System.Drawing.Printing.PrintDocument. Ключевой метод — обработчик события printDocument_PrintPage:

private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
    Graphics gr = e.Graphics ?? throw new InvalidOperationException("No 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 для печатаемой страницы. Важно учитывать параметры «По размеру страницы» и «Фактический размер». Мы также отображаем аппаратные поля принтера в диалоге предварительного просмотра печати. Затем мы отрисовываем текущую страницу PDF на объект Graphics, используя расширяющий метод PdfPage.Draw.

Класс 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;
    }
}

Вот и все. Чтобы реализовать печать PDF в приложении Windows Forms или WPF, выполните следующие действия:

  • добавьте файлы PdfPrintDocument, PdfPrintHelper и PrintSize из примера
  • добавьте ссылку на библиотеку Docotic.Pdf
  • добавьте ссылку на DLL расширения BitMiracle.Docotic.Pdf.Gdi
  • (только для WPF) добавьте ссылки на сборки System.Windows.Forms и System.Drawing

Классы из пространства имен System.Drawing.Printing хорошо работают в приложениях Windows Forms и WPF. Но есть случаи, когда использовать System.Drawing.Printing нельзя или не следует.

Например, не следует использовать System.Drawing.Printing в службах Windows или приложениях ASP.NET. System.Drawing.Printing может давать непоследовательные результаты при печати в Linux или macOS. И нельзя использовать System.Drawing.Printing в приложениях Eto.Forms или Avalonia.

В таких случаях сначала нужно преобразовать PDF-документ в изображение. Этот пример на C# показывает, как сохранить страницу PDF как изображение PNG или преобразовать весь PDF-документ в многостраничный 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);

Затем печатайте изображения с помощью альтернативного фреймворка или инструмента печати. Посмотрите демонстрационное приложение Печать PDF в Eto.Forms, которое показывает, как печатать PDF-документы без System.Drawing.Printing.

Отрисовка PDF в C# и VB.NET

Отображение PDF в вашем приложении похоже на печать. В ASP.NET, WPF, Eto.Forms, Avalonia или любом другом типе приложения сначала преобразуйте PDF в изображение, а затем отобразите его.

В приложении Windows Forms вы можете рисовать страницу PDF в контексте System.Drawing.Graphics из любого элемента управления. Или вы можете преобразовать страницу PDF в System.Drawing.Bitmap, а затем отобразить растровое изображение в PictureBox.

Этот пример показывает, как преобразовать страницу PDF в Bitmap на 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");

Для приведенного выше кода нужно добавить в проект DLL расширения BitMiracle.Docotic.Pdf.Gdi.

Создание просмотрщика PDF или редактора PDF в приложении .NET

Docotic.Pdf позволяет получать подробные сведения о каждом объекте на странице PDF. Вы можете извлекать фрагменты текста, изображения, векторные пути, элементы форм и аннотации со страницы PDF.

Затем в вашем приложении можно отрисовать все извлеченные объекты. Также можно реализовать возможность выбора и редактирования отрисованных объектов.

Посмотрите пример Извлечение текста, изображений и путей из PDF. Он показывает, как извлекать и отрисовывать объекты страницы в контексте System.Drawing.Graphics.

Вы также можете извлекать текстовые объекты как векторные пути. Для этого используйте перегрузку PdfPage.GetObjects(PdfObjectExtractionOptions).

Заключение

Используйте библиотеку Docotic.Pdf для отображения и печати PDF-документов в ваших проектах .NET. Смотрите связанные примеры на C# и VB.NET:

Свяжитесь с нами, если у вас есть вопросы о печати или отрисовке PDF.