共用方式為


列印文件概觀 (WPF .NET)

有了 Microsoft .NET,使用 Windows Presentation Foundation (WPF) 的應用程式開發人員等於擁有了一套豐富的列印與列印系統管理 API。 此功能的核心是 XML 文件規格 (XPS) 檔案格式和 XPS 列印路徑。

關於 XPS

XPS 是一種電子文件格式、多工緩衝檔案格式且為頁面描述語言。 其為一種開放文件格式,使用 XML、開放式封裝慣例 (OPC) 以及其他業界標準,來建立跨平台文件。 XPS 可簡化數位文件的建立、共用、列印、檢視和封存過程。 如需 XPS 的詳細資訊,請參閱 XPS 文件

XPS 列印路徑

XPS 列印路徑是 Windows 功能,重新定義了 Windows 應用程式中處理列印的方式。 XPS 列印路徑可以取代:

  • 文件簡報語言,例如 RTF 格式或 PDF。
  • 列印多工緩衝處理器格式,例如中繼檔或加強型中繼檔 (EMF)。
  • 頁面描述語言,例如印表機命令語言或 PostScript。

因此,XPS 列印路徑從應用程式發佈到印表機驅動程式或裝置的最終處理都保持 XPS 格式。

XPS 文件的列印多工緩衝處理器同時支援 XPS 列印路徑和 GDI 列印路徑。 XPS 列印路徑本身使用 XPS 多工緩衝處理檔案,而且需要 XPS 印表機驅動程式。 XPS 列印路徑建置在 XPS 印表機驅動程式 (XPSDrv) 模型上。

XPS 列印路徑的優點包括:

  • 所見即所得 (WYSIWYG) 列印支援。
  • 進階色彩設定檔的原生支援,例如每個通道 32 位元、CMYK 色彩模型、具名色彩、n-inks 和透明及漸層效果。
  • 改善的列印效能 - XPS 功能和增強功能僅適用於以 XPS 列印路徑為目標的應用程式。
  • 業界標準 XPS 格式。

對於基本的列印案例,可以使用簡單直覺的 API 和標準使用者介面來進行列印設定和工作提交。 對於進階案例,API 支援使用者介面自訂或完全無使用者介面、同步或非同步列印以及批次列印功能。 簡單和進階選項都提供完整或部分信任模式中的列印支援。

XPS 的設計考慮了可擴展性,因此能以模組化方式將特性和功能新增到 XPS 中。 擴充性功能包括:

  • 支援快速擴充裝置功能的列印結構描述。 結構描述的公用部分會定期更新,以新增所需的裝置功能。 如需詳細資訊,請參閱可延伸結構
  • XPSDrv 驅動程式使用可擴充的篩選管線來支援 XPS 文件的直接和可擴充列印。 如需詳細資訊,請參閱 XPSDrv 印表機驅動程式

WPF 應用程式原生支援 XPS 列印路徑,而且可以使用 XPS 列印 API 直接列印至 XPSDrv 驅動程式。 如果寫入作業的目標列印佇列沒有 XPSDrv 驅動程式,則 XpsDocumentWriter 類別的 WriteWriteAsync 方法會自動將內容從 XPS 轉換成 GDI 格式,以用於 GDI 列印路徑。

下圖顯示列印子系統,並定義 Microsoft 和獨立軟硬體供應商所提供的部分。

顯示 XPS 列印系統的螢幕擷取畫面。

基本 XPS 列印

WPF 具有列印 API,其支援基本和進階列印功能。 對於不需要大量列印自訂功能或不需存取完整 XPS 功能集的應用程式,基本的列印支援可能就足夠了。 基本列印支援透過 PrintDialog 控制項提供,其僅需基本設定,有熟悉的使用者介面且支援許多 XPS 功能。

PrintDialog

System.Windows.Controls.PrintDialog 控制項提供單一的進入點,用於使用者介面、設定及 XPS 工作提交。 若要了解如何實例化和使用該控制項,請參閱如何顯示列印對話方塊

進階的 XPS 列印

若要存取一組完整的 XPS 功能,請使用進階列印 API。 本節說明數個相關的 API,包括 PrintTicketPrintCapabilitiesPrintServerPrintQueueXpsDocumentWriter。 如需 XPS 列印路徑 API 的完整清單,請參閱 System.Windows.XpsSystem.Printing 命名空間。

PrintTicket 和 PrintCapabilities

PrintTicketPrintCapabilities 類別是進階 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 和其許多的 WriteWriteAsync 方法,可用來將 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 列印路徑,只要呼叫 XpsDocumentWriter 類別的其中一個 WriteWriteAsync 方法,並選取非 XpsDrv 印表機的列印佇列即可。

對於不需要 XPS 功能或支援的應用程式、目前的 GDI 列印路徑會維持不變。 如需 GDI 列印路徑和各種 XPS 轉換選項的相關資訊,請參閱 Microsoft XPS 文件轉換器 (MXDC)XPSDrv 印表機驅動程式

XPSDrv 驅動程式模型

XPS 列印路徑,將 XPS 作為原生列印多工緩衝處理格式,因此,當列印至支援 XPS 的印表機或驅動程式時,可有效提升多工緩衝處理器的效率。 不同於 EMF,EMF 將應用程式的輸出表示為一系列對 GDI 的呼叫,以執行轉譯服務,而 XPS 多工緩衝處理格式則表示文件。 因此,當 XPS 多工緩衝暫存檔案輸出至 XPS 型印表機驅動程式時,不需要進一步解譯,因為驅動程式會以該格式直接處理資料。 這項功能免除了 EMF 檔案和 GDI 型印表機驅動程式所需的資料和色彩空間轉換過程。

簡化的列印多工緩衝過程,不再需要先產生中間多工緩衝暫存檔案,例如 EMF 資料檔案,便可直接進行文件的多工緩衝暫存。 如果多工緩衝暫存檔案較小,XPS 列印路徑得以減少網路流量並改善列印效能。 相較於其相等的 EMF 檔案,XPS 多工緩衝暫存檔案的大小通常會在使用 XPS 列印路徑時縮減。 多工緩衝暫存檔案大小的縮減會透過數種機制執行:

  • 字型子集設定,僅將文件內使用的字元儲存在 XPS 檔案中。
  • 進階圖形支援,原生支援透明度和漸層基本類型,以避免 XPS 內容的點陣化。
  • 識別常見的資源,例如文件中多次使用的公司標誌圖片。 一般資源會被視為共享資源,而且只會載入一次。
  • ZIP 壓縮,用於所有 XPS 文件。

如果向量圖形非常複雜、多層或寫入效率低下,XPS 多工緩衝暫存檔案的大小可能不會縮減。 不同於 GDI 多工緩衝暫存檔案,XPS 檔案會針對螢幕顯示目的來內嵌裝置字型和電腦型字型,不過這兩種字型都是子集的,而且印表機驅動程式可以先移除裝置字型,再將檔案傳輸到印表機。

提示

您也可以使用 PrintQueue.AddJob 方法來列印 XPS 檔案。 如需詳細資訊,請參閱如何列印 XPS 檔案

另請參閱