ドキュメント印刷の概要 (WPF .NET)

Microsoft .NET では、Windows Presentation Foundation (WPF) を使用するアプリケーション開発者は、豊富な印刷および印刷システム管理 API を利用できます。 この機能の中核となるのが、XML Paper Specification (XPS) ファイル形式と XPS 印刷パスです。

XPS について

XPS は、電子ドキュメント形式、スプール ファイル形式、およびページ記述言語です。 XML、Open Packaging Conventions、その他の業界標を使用してクロスプラットフォームのドキュメントを作成する OpenDocument 形式の 1 つです。 XPS により、デジタル ドキュメントの作成、共有、印刷、表示、アーカイブを行うプロセスが簡略化されます。 XPS の詳細情報については、「XPS ドキュメント」を参照してください。

XPS 印刷パス

XPS 印刷パスは、Windows アプリケーションでの印刷の処理方法を再定義する Windows の機能です。 次のものを XPS 印刷パスで置き換えることができます。

  • リッチ テキスト形式や Portable Document Format などのドキュメント プレゼンテーション言語。
  • Windows メタファイルや拡張メタファイル (EMF) などの印刷スプーラー形式。
  • プリンター コマンド言語や PostScript などのページ記述言語。

その結果、XPS 印刷パスにおいては、アプリケーションの発行からプリンター ドライバーまたはデバイスでの最終処理に至るまで XPS 形式が維持されます。

XPS ドキュメントの印刷スプーラーによって、XPS 印刷パスと GDI 印刷パスの両方がサポートされます。 XPS 印刷パスは、XPS スプール ファイルをネイティブに使用し、XPS プリンター ドライバーを必要とします。 XPS 印刷パスは、XPS プリンター ドライバー (XPSDrv) モデルに基づいて構築されています。

XPS 印刷パスには次のような利点があります。

  • WYSIWYG 印刷のサポート。
  • 高度なカラー プロファイルのネイティブ サポート (1 チャンネルあたり 32 ビット、CMYK カラー モデル、名前付きの色、n インク、透明度、グラデーションなど)。
  • 印刷パフォーマンスの向上。XPS の機能と拡張機能は、XPS 印刷パスを対象としたアプリケーションのみで使用できます。
  • 業界標準の XPS 形式。

基本的な印刷シナリオの場合、印刷の構成とジョブの送信用の標準 UI で、簡単かつ直感的な API を使用できます。 高度なシナリオ用に、UI のカスタマイズ (または UI をまったく使用しない)、同期または非同期の印刷、および一括印刷の機能が API でサポートされています。 基本的と高度のいずれのオプションでも、完全または部分的な信頼モードでの印刷のサポートが提供されます。

XPS は拡張性を考慮して設計されているので、モジュール方式で機能を XPS に追加できます。 拡張機能は、次のとおりです。

  • デバイスの機能の迅速な拡張をサポートする印刷スキーマ。 スキーマの公開部分は、必要なデバイス機能を追加するために定期的に更新されます。 詳細については、「拡張可能なアーキテクチャ」を参照してください。
  • XPSDrv ドライバーで XPS ドキュメントの直接およびスケーラブルな印刷の両方をサポートするために使用される、拡張可能なフィルター パイプライン。 詳細については、「XPSDrv プリンター ドライバー」を参照してください。

WPF アプリケーションで XPS 印刷パスをネイティブにサポートし、XPS 印刷 API を使用して XPSDrv ドライバーに直接印刷できます。 書き込み操作の対象の印刷キューに XPSDrv ドライバーがない場合は、XpsDocumentWriter クラスの Write および WriteAsync メソッドによって、GDI 印刷パスのコンテンツが XPS から GDI 形式に自動的に変換されます。

次の図は、印刷サブシステムを示すとともに、Microsoft と独立系のソフトウェアおよびハードウェアのベンダーによって提供される部分を定義しています。

Screenshot showing the XPS print system.

XPS の基本的な印刷

WPF には、基本的と高度の両方の印刷機能をサポートする印刷 API が用意されています。 広範な印刷のカスタマイズや完全な XPS の機能セットへのアクセスを必要としないアプリケーションでは、基本的な印刷サポートで十分な可能性があります。 基本的な印刷サポートは、最小構成を必要とし、使い慣れた UI を備え、多数の XPS 機能をサポートする PrintDialog コントロールを介して提供されます。

PrintDialog

System.Windows.Controls.PrintDialog コントロールには、UI、構成、および XPS ジョブの送信用に 1 つのエントリ ポイントが用意されています。 コントロールのインスタンス作成および使用方法については、「印刷ダイアログを表示する方法」を参照してください。

高度な XPS の印刷

XPS 機能の完全なセットにアクセスするには、高度な印刷 API を使用します。 このセクションでは、PrintTicketPrintCapabilitiesPrintServerPrintQueueXpsDocumentWriter など、関連するいくつかの API について説明します。 XPS 印刷パス API の完全な一覧については、System.Windows.Xps および System.Printing 名前空間を参照してください。

PrintTicket と PrintCapabilities

PrintTicket および PrintCapabilities クラスは、XPS の高度な機能の基盤となります。 両方のオブジェクトに、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 印刷パスはネイティブにサポートされていますが、XpsDocumentWriter クラスの Write または WriteAsync メソッドのいずれかを呼び出し、XpsDrv 以外のプリンターの印刷キューを選択することによって、GDI 印刷パスに出力することもできます。

XPS の機能またはサポートを必要としないアプリケーションの場合、現在の GDI 印刷パスは変更されません。 GDI 印刷パスとさまざまな XPS 変換オプションに関するその他の関連資料については、「Microsoft XPS Document Converter (MXDC)」および「XPSDrv プリンター ドライバー」を参照してください。

XPSDrv ドライバー モデル

XPS 印刷パスでは、XPS 対応のプリンターまたはドライバーに出力する場合に、ネイティブの印刷スプール形式として XPS を使用すると、スプーラーの効率性が高まります。 レンダリング サービスのためにアプリケーションの出力を GDI に対する一連の呼び出しとして表す EMF とは異なり、XPS スプール形式はドキュメントを表します。 そのため、XPS スプール ファイルが XPS ベースのプリンター ドライバーに出力されるときに、その形式のデータがドライバーで直接操作されるため、それ以上の解釈は必要ありません。 この機能により、EMF ファイルと GDI ベースの印刷ドライバーのためにデータと色空間を変換する必要がなくなります。

スプール処理の簡略化により、ドキュメントをスプールする前に、EMF データ ファイルなどの中間スプール ファイルを生成する必要がなくなります。 スプール ファイルのサイズを小さくすると、XPS 印刷パスのネットワーク トラフィックが減少し、印刷のパフォーマンスが向上します。 相当する EMF のものと比較して、XPS のスプール ファイルのサイズは、XPS 印刷パスを使用すると一般に小さくなります。 スプール ファイル サイズの削減は、いくつかのメカニズムを通じて行われます。

  • フォントのサブセット化。ドキュメント内で使用されている文字だけが XPS ファイルに格納されます。
  • 高度なグラフィックス サポート。XPS コンテンツのラスタライズを避けるために、透明度とグラデーションのプリミティブがネイティブにサポートされています。
  • ドキュメント内で複数回使用される会社のロゴの画像など、共通リソースの識別。 共通リソースは共有リソースとして扱われ、一度だけ読み込まれます。
  • ZIP 圧縮。すべての XPS ドキュメントに対して使用されます。

ベクター グラフィックスが非常に複雑であるか、複数のレイヤーがあるか、非効率的に記述されている場合、XPS スプール ファイルのサイズが小さくならない可能性があります。 GDI のスプール ファイルとは異なり、XPS ファイルには、画面表示を目的としてデバイス フォントとコンピューターベースのフォントが埋め込まれていますが、この両方の種類のフォントはサブセット化されており、ファイルをプリンターに転送する前にプリンター ドライバーでデバイス フォントを削除することができます。

ヒント

また、PrintQueue.AddJob メソッドを使用して XPS ファイルを印刷することもできます。 詳細については、「XPS ファイルの印刷方法」を参照してください。

関連項目