Общие сведения о печати документов (.NET в WPF)

Microsoft .NET предоставляет разработчикам приложений на базе Windows Presentation Foundation (WPF) широкий набор API-интерфейсов для печати и управления системой печати. В основе этих функциональных возможностей лежит файловый формат XPS (XML Paper Specification) и новый способ печати этого формата.

О формате XPS

XPS — это формат электронного документа, формат файла очереди и язык описания страницы. Это открытый формат документов, в котором используется стандарты XML, Open Packaging Conventions и другие отраслевые стандарты, предназначенные для создания кроссплатформенных документов. XPS упрощает процесс создания, совместного использования, печати, просмотра и архивирования цифровых документов. Дополнительные сведения см. в статье Документы XPS.

Способ печати на основе XPS

Способ печати на основе XPS — это функция ОС Windows, которая по-новому определяет то, как процесс печати обрабатывается в Windows-приложениях. Способ печати на основе XPS может заменить следующее:

  • языки презентации документов, такие как RTF или PDF;
  • форматы диспетчера очереди печати, такие как WMF или EMF;
  • языки описания страниц, такие как Printer Command Language или PostScript.

Следовательно, способ печати на основе XPS поддерживает формат XPS от публикации приложения вплоть до окончательной обработки в драйвере или принтера или на устройстве.

Диспетчер очереди печати для документов XPS поддерживает способ печати как на основе XPS, так и на основе GDI. Способ печати на основе XPS нативно использует файл очереди XPS и требует драйвера принтера XPS. Способ печати на основе XPS базируется на модели драйвера принтера XPS (XPSDrv).

К преимуществам способа печати на основе XPS относятся:

  • Поддержка печати в режиме WYSIWYG.
  • Встроенная поддержка дополнительных цветовых профилей, включая 32 бита на канал, цветовую модель CMYK, именованные цвета, а также поддержку прозрачности и градиентов.
  • Повышенная производительность печати. Функции и усовершенствования XPS доступны только приложениям, оптимизированным для способа печати на основе XPS.
  • Поддержка стандартного промышленного формата XPS.

Для базовых сценариев печати доступен простой и понятный API-интерфейс со стандартным пользовательским интерфейсом для настройки печати и отправки заданий. Для расширенных сценариев API поддерживает настройку пользовательского интерфейса или работу вообще без него, синхронную или асинхронную печать и возможности пакетной печати. Как простые, так и расширенные параметры обеспечивают поддержку печати в режиме полного или частичного доверия.

Формат XPS был разработан с учетом расширяемости, поэтому функции и возможности можно добавлять в XPS на модульной основе. Функции расширяемости включают следующее.

  • Схема печати, поддерживающая быстрое расширение возможностей устройств. Общедоступная часть схемы регулярно обновляется, чтобы можно было добавить необходимые возможности устройства. Дополнительные сведения см. в статье Расширяемая архитектура.
  • Расширяемый конвейер фильтров, с помощью которого драйверы XPSDrv поддерживают прямую и масштабируемую печать документов XPS. Дополнительные сведения см. в разделе Драйверы принтера XPSDrv.

Приложения WPF нативно поддерживают способ печати на основе XPS и с помощью API-интерфейсов печати XPS могут выполнять печать непосредственно в драйвер XPSDrv. Если в целевой очереди печати операции записи нет драйвера XPSDrv, методы Write и WriteAsync класса XpsDocumentWriter будут автоматически преобразовывать содержимое из формата XPS в GDI для способа печати на основе GDI.

На следующей иллюстрации изображена подсистема печати и определены части, предоставляемые Майкрософт, а также независимыми поставщиками программного обеспечения и оборудования.

Screenshot showing the XPS print system.

Базовая печать XPS

В WPF есть API печати, который поддерживает как базовые, так и расширенные функции печати. Для приложений, которым не требуется настройка расширенной печати или доступ к полному набору функций XPS, может подойти базовая поддержка печати. Базовая поддержка печати предоставляется с помощью элемента управления PrintDialog. Он требует минимальной настройки, имеет привычный пользовательский интерфейс и поддерживает многие функции XPS.

PrintDialog

Элемент управления System.Windows.Controls.PrintDialog предоставляет единую точку входа для пользовательского интерфейса, конфигурации и отправки задания XPS. Чтобы узнать, как создать экземпляр элемента управления и использовать его, см. статью Как отобразить диалоговое окно печати.

Расширенная печать XPS

Для доступа к полному набору функций XPS используйте расширенный API-интерфейс печати. В этом разделе описано несколько соответствующих API-интерфейсов, включая PrintTicket, PrintCapabilities, PrintServer, PrintQueue и XpsDocumentWriter. Полный список API-интерфейсов для способов печати XPS см. в статьях о пространствах имен System.Windows.Xps и System.Printing.

PrintTicket и PrintCapabilities

Основой расширенных функций XPS являются классы PrintTicket и PrintCapabilities. Оба объекта содержат структуры функций в формате XML, ориентированных на печать и определяемых схемой печати. К ним относятся дуплексирование, параметры сортировки, двусторонняя печать и сшивание. Объект PrintTicket указывает принтеру, как обрабатывать задание печати. Класс PrintCapabilities определяет возможности принтера. Запрашивая возможности принтера, можно создать PrintTicket, который использует все преимущества поддерживаемых возможностей принтера. Аналогичным образом можно избежать неподдерживаемых функций.

В следующем примере выполняется запрос к PrintCapabilities принтера и с помощью кода создается PrintTicket.

/// <summary>
/// Returns a print ticket, which is a set of instructions telling a printer how
/// to set its various features, such as duplexing, collating, and stapling.
/// </summary>
/// <param name="printQueue">The print queue to print to.</param>
/// <returns>A print ticket.</returns>
public static PrintTicket GetPrintTicket(PrintQueue printQueue)
{
    PrintCapabilities printCapabilites = printQueue.GetPrintCapabilities();

    // Get a default print ticket from printer.
    PrintTicket printTicket = printQueue.DefaultPrintTicket;

    // Modify the print ticket.
    if (printCapabilites.CollationCapability.Contains(Collation.Collated))
        printTicket.Collation = Collation.Collated;
    if (printCapabilites.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge))
        printTicket.Duplexing = Duplexing.TwoSidedLongEdge;
    if (printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft))
        printTicket.Stapling = Stapling.StapleDualLeft;

    // Returns a print ticket, which is a set of instructions telling a printer how
    // to set its various features, such as duplexing, collating, and stapling.
    return printTicket;
}
''' <summary>
''' Returns a print ticket, which is a set of instructions telling a printer how
''' to set its various features, such as duplexing, collating, and stapling.
''' </summary>
''' <param name="printQueue">The print queue to print to.</param>
''' <returns>A print ticket.</returns>
Public Shared Function GetPrintTicket(printQueue As PrintQueue) As PrintTicket

    Dim printCapabilites As PrintCapabilities = printQueue.GetPrintCapabilities()

    ' Get a default print ticket from printer.
    Dim printTicket As PrintTicket = printQueue.DefaultPrintTicket

    ' Modify the print ticket.
    If printCapabilites.CollationCapability.Contains(Collation.Collated) Then
        printTicket.Collation = Collation.Collated
    End If
    If printCapabilites.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge) Then
        printTicket.Duplexing = Duplexing.TwoSidedLongEdge
    End If
    If printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft) Then
        printTicket.Stapling = Stapling.StapleDualLeft
    End If

    ' Returns a print ticket, which is a set of instructions telling a printer how
    ' to set its various features, such as duplexing, collating, and stapling.
    Return printTicket

End Function

PrintServer и PrintQueue

Класс PrintServer представляет сетевой сервер печати, а класс PrintQueue представляет принтер и связанную с ним очередь выходных заданий. Вместе эти API-интерфейсы поддерживают расширенное управление заданиями печати для сервера. Объект PrintServer или один из его производных классов используется для управления PrintQueue.

В следующем примере создается LocalPrintServer и с использованием кода PrintQueueCollection осуществляется доступ к локальному компьютеру.

/// <summary>
/// Return a collection of print queues, which individually hold the features or states
/// of a printer as well as common properties for all print queues.
/// </summary>
/// <returns>A collection of print queues.</returns>
public static PrintQueueCollection GetPrintQueues()
{
    // Create a LocalPrintServer instance, which represents 
    // the print server for the local computer.
    LocalPrintServer localPrintServer = new();

    // Get the default print queue on the local computer.
    //PrintQueue printQueue = localPrintServer.DefaultPrintQueue;

    // Get all print queues on the local computer.
    PrintQueueCollection printQueueCollection = localPrintServer.GetPrintQueues();

    // Return a collection of print queues, which individually hold the features or states
    // of a printer as well as common properties for all print queues.
    return printQueueCollection;
}
''' <summary>
''' Return a collection of print queues, which individually hold the features or states
''' of a printer as well as common properties for all print queues.
''' </summary>
''' <returns>A collection of print queues.</returns>
Public Shared Function GetPrintQueues() As PrintQueueCollection

    ' Create a LocalPrintServer instance, which represents 
    ' the print server for the local computer.
    Dim localPrintServer As LocalPrintServer = New LocalPrintServer()

    ' Get the default print queue on the local computer.
    'Dim  printQueue As PrintQueue = localPrintServer.DefaultPrintQueue

    ' Get all print queues on the local computer.
    Dim printQueueCollection As PrintQueueCollection = localPrintServer.GetPrintQueues()

    ' Return a collection of print queues, which individually hold the features or states
    ' of a printer as well as common properties for all print queues.
    Return printQueueCollection

End Function

XpsDocumentWriter

XpsDocumentWriter и множество его методов Write и WriteAsync используются для добавления документов XPS в PrintQueue. Например, метод Write(FixedDocumentSequence, PrintTicket) используется для синхронного добавления в очередь документа XPS с билетом печати. Метод WriteAsync(FixedDocumentSequence, PrintTicket) используется для асинхронного добавления в очередь документа XPS с билетом печати.

В следующем примере создается XpsDocumentWriter и документы XPS как синхронно, так и асинхронно добавляются в PrintQueue с использованием кода.

/// <summary>
/// Asynchronously, add the XPS document together with a print ticket to the print queue.
/// </summary>
/// <param name="xpsFilePath">Path to source XPS file.</param>
/// <param name="printQueue">The print queue to print to.</param>
/// <param name="printTicket">The print ticket for the selected print queue.</param>
public static void PrintXpsDocumentAsync(string xpsFilePath, PrintQueue printQueue, PrintTicket printTicket)
{
    // Create an XpsDocumentWriter object for the print queue.
    XpsDocumentWriter xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);

    // Open the selected document.
    XpsDocument xpsDocument = new(xpsFilePath, FileAccess.Read);

    // Get a fixed document sequence for the selected document.
    FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();

    // Asynchronously, add the XPS document together with a print ticket to the print queue.
    xpsDocumentWriter.WriteAsync(fixedDocSeq, printTicket);
}

/// <summary>
/// Synchronously, add the XPS document together with a print ticket to the print queue.
/// </summary>
/// <param name="xpsFilePath">Path to source XPS file.</param>
/// <param name="printQueue">The print queue to print to.</param>
/// <param name="printTicket">The print ticket for the selected print queue.</param>
public static void PrintXpsDocument(string xpsFilePath, PrintQueue printQueue, PrintTicket printTicket)
{
    // Create an XpsDocumentWriter object for the print queue.
    XpsDocumentWriter xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);

    // Open the selected document.
    XpsDocument xpsDocument = new(xpsFilePath, FileAccess.Read);

    // Get a fixed document sequence for the selected document.
    FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();

    // Synchronously, add the XPS document together with a print ticket to the print queue.
    xpsDocumentWriter.Write(fixedDocSeq, printTicket);
}
''' <summary>
''' Asynchronously, add the XPS document together with a print ticket to the print queue.
''' </summary>
''' <param name="xpsFilePath">Path to source XPS file.</param>
''' <param name="printQueue">The print queue to print to.</param>
''' <param name="printTicket">The print ticket for the selected print queue.</param>
Public Shared Sub PrintXpsDocumentAsync(xpsFilePath As String, printQueue As PrintQueue, printTicket As PrintTicket)

    ' Create an XpsDocumentWriter object for the print queue.
    Dim xpsDocumentWriter As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue)

    ' Open the selected document.
    Dim xpsDocument As XpsDocument = New XpsDocument(xpsFilePath, FileAccess.Read)

    ' Get a fixed document sequence for the selected document.
    Dim fixedDocSeq As FixedDocumentSequence = xpsDocument.GetFixedDocumentSequence()

    ' Asynchronously, add the XPS document together with a print ticket to the print queue.
    xpsDocumentWriter.WriteAsync(fixedDocSeq, printTicket)

End Sub

''' <summary>
''' Synchronously, add the XPS document together with a print ticket to the print queue.
''' </summary>
''' <param name="xpsFilePath">Path to source XPS file.</param>
''' <param name="printQueue">The print queue to print to.</param>
''' <param name="printTicket">The print ticket for the selected print queue.</param>
Public Shared Sub PrintXpsDocument(xpsFilePath As String, printQueue As PrintQueue, printTicket As PrintTicket)

    ' Create an XpsDocumentWriter object for the print queue.
    Dim xpsDocumentWriter As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue)

    ' Open the selected document.
    Dim xpsDocument As XpsDocument = New XpsDocument(xpsFilePath, FileAccess.Read)

    ' Get a fixed document sequence for the selected document.
    Dim fixedDocSeq As FixedDocumentSequence = xpsDocument.GetFixedDocumentSequence()

    ' Synchronously, add the XPS document together with a print ticket to the print queue.
    xpsDocumentWriter.Write(fixedDocSeq, printTicket)

End Sub

Путь печати GDI

Хотя приложения WPF нативно поддерживают способ печати на основе XPS, они также могут выполнять вывод способом печати на основе GDI. Для этого вызывается метод Write или WriteAsync класса XpsDocumentWriter и выбирается очередь печати для принтера, отличного от XpsDrv.

Для приложений, которым не требуются функциональные возможности или поддержка XPS, текущий способ печати GDI остается прежним. Дополнительные сведения о способе печати GDI и о различных вариантах преобразования для формата XPS см. в статьях Конвертер документов Microsoft XPS (MXDC) и Драйверы принтера XPSDrv.

Модель драйвера XPSDrv

Способ печати XPS повышает эффективность очереди печати путем использования XPS в качестве собственного формата очереди печати при выводе печати на принтер или в драйвер с поддержкой XPS. В отличие от EMF, представляющего выходные данные приложения в виде ряда вызовов GDI для служб отрисовки, формат очереди XPS представляет документ. Таким образом, если файлы очереди XPS выводятся в драйвер принтера на основе XPS, они не требуют дальнейшей интерпретации, так как драйверы работают непосредственно с данными в этом формате. Эта возможность позволяет избежать преобразования данных и цветового пространства, необходимого для файлов EMF и драйверов печати на основе GDI.

Упрощенный процесс постановки в очередь избавляет от необходимости создания промежуточных файлов очередей, таких как файл данных EMF, до помещения документа в очередь. Благодаря меньшим размерам файлов очереди способ печати XPS может сократить сетевой трафик и повысить производительность печати. По сравнению с эквивалентами EMF размеры файлов очереди XPS обычно сокращаются при использовании способа печати на основе XPS. Размер файла очереди уменьшается с помощью нескольких механизмов:

  • Поднабор шрифта, в котором хранятся только символы, используемые в документе в XPS-файле.
  • Расширенная поддержка графики, при которой нативно поддерживаются примитивы прозрачности и градиентов, чтобы избежать растеризации содержимого XPS.
  • Идентификация общих ресурсов, таких как образ корпоративного логотипа, который несколько раз используется в документе. Общие ресурсы обрабатываются как совместно используемые и загружаются только один раз.
  • Сжатие в формате ZIP, используемое во всех документах XPS.

Возможно, размер файла очереди XPS не удастся уменьшить, если векторная графика является очень сложной, многоуровневой или неэффективно написанной. В отличие от файлов очереди GDI, XPS-файлы внедряют шрифты устройств и компьютерные шрифты для отображения экрана, хотя оба типа шрифтов помещены в поднабор, а драйверы принтера могут удалять шрифты устройств перед передачей файла на принтер.

Совет

Кроме того, файлы XPS можно распечатать с помощью методов PrintQueue.AddJob. Дополнительные сведения см. в статье Как выполнять печать файлов XPS.

См. также