Общие сведения о печати

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

Эта тема описана в следующих разделах.

О формате XPS

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

Несколько методов печати содержимого на основе XPS с помощью WPF демонстрируются в разделе Печать XPS-файлов программным способом. Ссылки на эти примеры могут оказаться полезными при просмотре содержимого этого раздела. (Разработчикам неуправляемого кода следует ознакомиться с документацией по функции MXDC_ESCAPE. Разработчикам Windows Forms нужно использовать в пространстве имен System.Drawing.Printing интерфейс API, который не поддерживает весь способ печати XPS, но поддерживает гибридный способ печати "GDI-в-XPS". См. раздел Архитектура способа печати ниже.)

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

Способ печати на основе XPS (XML Paper Specification) является новой функцией ОС Windows, которая по-новому определяет то, как процесс печати обрабатывается в Windows-приложениях. Поскольку XPS может заменить язык представления документов (например, RTF), формат очереди печати (например, WMF) и язык описания страницы (например, PCL или Postscript), новый способ печати поддерживает формат XPS от публикации приложения до последней обработки в драйвере печати или устройстве печати.

Способ печати XPS построен на основе модели драйвера печати XPS (XPSDrv), которая предоставляет разработчикам различные эффективные возможности, такие как печать в «режиме точного отображения» (WYSIWYG), улучшенная поддержка цвета и значительно повышенная производительность печати. (Дополнительные сведения о XPSDrv см в документации из пакета разработки драйверов Windows .)

Очередь печати принтера для документов XPS функционирует в основном так же, как в предыдущих версиях ОС Windows. Однако она была усовершенствована для поддержки способа печати XPS в дополнение к имеющемуся в GDI способу печати. В новом способе печати используется файл очереди XPS. Хотя драйверы принтеров пользовательского режима, написанные для предыдущих версий ОС Windows, будут продолжать работать, для использования способа печати XPS необходим драйвер принтера XPS (XPSDrv).

Способа печати XPS обладает следующими существенными преимуществами:

  • Поддержка печати в режиме WYSIWYG

  • Встроенная поддержка дополнительных цветовых профилей, включая 32 бита на канал (bpc), CMYK, именованные цвета, n-краски и встроенную поддержку прозрачности и градиентов.

  • Улучшенная производительность печати для приложений, основанных на платформах .NET Framework и Win32.

  • Поддержка стандартного промышленного формата XPS.

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

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

  • Схема печати. Общая схема обновляется регулярно и позволяет быстро расширять возможности устройства. (См. PrintTicket и PrintCapabilities ниже.)

  • Расширяемый конвейер фильтра. Конвейер фильтра драйвера принтера XPS (XPSDrv) был разработан для включения как прямой, так и масштабируемой печати документов XPS. Дополнительные сведения см. в разделе Драйверы принтера XPSDrv.

Хотя в приложениях на платформах Win32 и .NET Framework поддерживается XPS, в приложениях Win32 и Windows Forms используется преобразование из формата GDI в формат XPS для создания содержимого в формате XPS, совместимого с драйвером принтера XPS (XPSDrv). В этих приложения не требуется использовать способ печати XPS, и можно по прежнему выполнять печать на основе формата Enhanced Metafile (EMF). Однако большинство функций и усовершенствований XPS доступно только приложениям, оптимизированным для способа печати XPS.

Чтобы включить использование приложениями Win32 и Windows Forms принтеров на основе XPSDrv, в драйвере принтера XPS (XPSDrv) поддерживается преобразование из формата GDI в формат XPS. Модель XPSDrv также предоставляет средство для преобразования из формата XPS в формат GDI, чтобы в приложениях Win32 можно было печатать документы XPS. В приложениях WPF преобразование из формата XPS в формат GDI выполняется автоматически с помощью методов Write и WriteAsync из класса XpsDocumentWriter, каждый раз, когда в целевой очереди печати операции записи отсутствует драйвер XPSDrv. (Приложения Windows Forms не могут выполнять печать документов XPS.)

На следующем рисунке изображена подсистема печати, а также определены части, предоставляемые Microsoft, и части, определенные поставщиками программного обеспечения и оборудования:

Screenshot shows the XPS print system.

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

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

PrintDialog

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

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

Для доступа к полному набору функций XPS необходимо использовать расширенный API-интерфейс печати. Некоторые соответствующие API-интерфейсы более подробно описываются ниже. Полный список API-интерфейсов для способов печати XPS см. в справочниках по пространствам имен System.Windows.Xps и System.Printing.

PrintTicket и PrintCapabilities

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

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

// ---------------------- GetPrintTicketFromPrinter -----------------------
/// <summary>
///   Returns a PrintTicket based on the current default printer.</summary>
/// <returns>
///   A PrintTicket for the current local default printer.</returns>
PrintTicket^ GetPrintTicketFromPrinter () 
{
   PrintQueue^ printQueue = nullptr;

   LocalPrintServer^ localPrintServer = gcnew LocalPrintServer();

   // Retrieving collection of local printer on user machine
   PrintQueueCollection^ localPrinterCollection = localPrintServer->GetPrintQueues();

   System::Collections::IEnumerator^ localPrinterEnumerator = localPrinterCollection->GetEnumerator();

   if (localPrinterEnumerator->MoveNext())
   {
      // Get PrintQueue from first available printer
      printQueue = ((PrintQueue^)localPrinterEnumerator->Current);
   } else
   {
      return nullptr;
   }
   // Get default PrintTicket from printer
   PrintTicket^ printTicket = printQueue->DefaultPrintTicket;

   PrintCapabilities^ printCapabilites = printQueue->GetPrintCapabilities();

   // Modify PrintTicket
   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;
   }
   return printTicket;
};// end:GetPrintTicketFromPrinter()
// ---------------------- GetPrintTicketFromPrinter -----------------------
/// <summary>
///   Returns a PrintTicket based on the current default printer.</summary>
/// <returns>
///   A PrintTicket for the current local default printer.</returns>
private PrintTicket GetPrintTicketFromPrinter()
{
    PrintQueue printQueue = null;

    LocalPrintServer localPrintServer = new LocalPrintServer();

    // Retrieving collection of local printer on user machine
    PrintQueueCollection localPrinterCollection =
        localPrintServer.GetPrintQueues();

    System.Collections.IEnumerator localPrinterEnumerator =
        localPrinterCollection.GetEnumerator();

    if (localPrinterEnumerator.MoveNext())
    {
        // Get PrintQueue from first available printer
        printQueue = (PrintQueue)localPrinterEnumerator.Current;
    }
    else
    {
        // No printer exist, return null PrintTicket
        return null;
    }

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

    PrintCapabilities printCapabilites = printQueue.GetPrintCapabilities();

    // Modify PrintTicket
    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;
    }

    return printTicket;
}// end:GetPrintTicketFromPrinter()
' ---------------------- GetPrintTicketFromPrinter -----------------------
''' <summary>
'''   Returns a PrintTicket based on the current default printer.</summary>
''' <returns>
'''   A PrintTicket for the current local default printer.</returns>
Private Function GetPrintTicketFromPrinter() As PrintTicket
    Dim printQueue As PrintQueue = Nothing

    Dim localPrintServer As New LocalPrintServer()

    ' Retrieving collection of local printer on user machine
    Dim localPrinterCollection As PrintQueueCollection = localPrintServer.GetPrintQueues()

    Dim localPrinterEnumerator As System.Collections.IEnumerator = localPrinterCollection.GetEnumerator()

    If localPrinterEnumerator.MoveNext() Then
        ' Get PrintQueue from first available printer
        printQueue = CType(localPrinterEnumerator.Current, PrintQueue)
    Else
        ' No printer exist, return null PrintTicket
        Return Nothing
    End If

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

    Dim printCapabilites As PrintCapabilities = printQueue.GetPrintCapabilities()

    ' Modify PrintTicket
    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

    Return printTicket
End Function ' end:GetPrintTicketFromPrinter()

PrintServer и PrintQueue

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

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

// -------------------- GetPrintXpsDocumentWriter() -------------------
/// <summary>
///   Returns an XpsDocumentWriter for the default print queue.</summary>
/// <returns>
///   An XpsDocumentWriter for the default print queue.</returns>
private XpsDocumentWriter GetPrintXpsDocumentWriter()
{
    // Create a local print server
    LocalPrintServer ps = new LocalPrintServer();

    // Get the default print queue
    PrintQueue pq = ps.DefaultPrintQueue;

    // Get an XpsDocumentWriter for the default print queue
    XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
    return xpsdw;
}// end:GetPrintXpsDocumentWriter()
' -------------------- GetPrintXpsDocumentWriter() -------------------
''' <summary>
'''   Returns an XpsDocumentWriter for the default print queue.</summary>
''' <returns>
'''   An XpsDocumentWriter for the default print queue.</returns>
Private Function GetPrintXpsDocumentWriter() As XpsDocumentWriter
    ' Create a local print server
    Dim ps As New LocalPrintServer()

    ' Get the default print queue
    Dim pq As PrintQueue = ps.DefaultPrintQueue

    ' Get an XpsDocumentWriter for the default print queue
    Dim xpsdw As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(pq)
    Return xpsdw
End Function ' end:GetPrintXpsDocumentWriter()

XpsDocumentWriter

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

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

// -------------------- GetPrintXpsDocumentWriter() -------------------
/// <summary>
///   Returns an XpsDocumentWriter for the default print queue.</summary>
/// <returns>
///   An XpsDocumentWriter for the default print queue.</returns>
private XpsDocumentWriter GetPrintXpsDocumentWriter()
{
    // Create a local print server
    LocalPrintServer ps = new LocalPrintServer();

    // Get the default print queue
    PrintQueue pq = ps.DefaultPrintQueue;

    // Get an XpsDocumentWriter for the default print queue
    XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
    return xpsdw;
}// end:GetPrintXpsDocumentWriter()
' -------------------- GetPrintXpsDocumentWriter() -------------------
''' <summary>
'''   Returns an XpsDocumentWriter for the default print queue.</summary>
''' <returns>
'''   An XpsDocumentWriter for the default print queue.</returns>
Private Function GetPrintXpsDocumentWriter() As XpsDocumentWriter
    ' Create a local print server
    Dim ps As New LocalPrintServer()

    ' Get the default print queue
    Dim pq As PrintQueue = ps.DefaultPrintQueue

    ' Get an XpsDocumentWriter for the default print queue
    Dim xpsdw As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(pq)
    Return xpsdw
End Function ' end:GetPrintXpsDocumentWriter()

Методы AddJob также предоставляют способы печати. Дополнительные сведения см. в разделе Печать XPS-файлов программным способом. .

Способ печати GDI

В приложения WPF поддержка способа печати XPS встроена изначально, но приложения Win32 и Windows Forms также могут использовать расширенные возможности некоторых функций XPS. Драйвер принтера XPS (XPSDrv) может преобразовывать выходные данные GDI в формат XPS. Для более сложных сценариев поддерживается настраиваемое преобразование содержимого с помощью конвертера документов XPS Microsoft. Аналогичным образом приложения WPF могут также выполнять вывод в способ печати GDI путем вызова одного из методов Write или WriteAsync из класса XpsDocumentWriter и назначения принтера, не являющегося принтером XpsDrv, в качестве целевой очереди печати.

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

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

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

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

Размеры файлов очереди обычно уменьшаются при использовании документов XPS, предназначенных для драйвера принтера XPS (XPSDrv), по сравнению с их эквивалентами EMF; однако бывают следующие исключения:

  • Очень сложная, многоуровневая или неэффективно созданная векторная графика может быть больше, чем растровая версия того же графического объекта.

  • Для отображения экрана XPS-файлы внедряют шрифты устройства, а также шрифты на компьютере; тогда как файлы очереди GDI не внедряют шрифты устройства. Но оба типа шрифтов имеют поднаборы (см. ниже), и драйверы принтера могут удалить шрифты устройства до передачи файла на принтер.

Уменьшение размера очереди выполняется посредством нескольких механизмов.

  • Поднабор шрифта. В файле XPS хранятся только символы, используемые в документе.

  • Поддержка расширенной графики. Встроенная поддержка прозрачности и примитивов градиента позволяет избежать растеризации содержимого в документе XPS.

  • Идентификация общих ресурсов. Ресурсы, которые используются несколько раз (например, изображение, представляющее эмблему организации), рассматриваются как общие ресурсы и загружаются только один раз.

  • Сжатие ZIP. Во всех документах XPS используется сжатие ZIP.

См. также