如何列印 XPS 檔案 (WPF .NET)
有時您會想要將新的列印工作新增至列印佇列,而不要開啟列印對話方塊。 您可以使用其中一種 PrintQueue.AddJob 方法來這麼做。 方法如下。
在下列範例中,我們使用 AddJob(String, String, Boolean) 方法 (AddJob
的數種多載之一) 來執行下列作業:
- 將 XML 文件規格 (XPS) 文件的新列印工作新增至預設的列印佇列。
- 命名新工作。
- 指定是否應該驗證 XPS 文件 (使用
fastCopy
參數)。
使用 AddJob(String, String, Boolean)
方法時,fastCopy
參數的值是一個重要考慮因素:
- 如果您將
fastCopy
參數設定為true
,則會略過 XPS 驗證,而且列印作業會快速多工緩衝處理,而不會產生逐頁處理進度意見反應。 - 如果您將
fastCopy
參數設定為false
,則呼叫AddJob
方法的執行緒必須具有單一執行緒 Apartment 狀態,否則將會擲回例外狀況。 如需詳細資訊,請參閱備註一節中的 AddJob(String, String, Boolean)。
將新的列印工作新增至佇列
此範例會將一或多個 XPS 文件新增至預設佇列。 程式碼會:
- 使用 Task.Run 來避免封鎖 UI 執行緒,因為沒有非同步版本的
AddJob
。 - 如果
fastCopy
參數值為false
,請在具有單一執行緒 Apartment 狀態的執行緒上執行 AddJob(String, String, Boolean)。 - 取得 LocalPrintServer 的預設 PrintQueue 的參考。
- 在列印佇列參考上呼叫
AddJob(String, String, Boolean)
、傳入工作名稱、XPS 文件路徑和fastCopy
參數。
如果佇列未暫停且印表機正在運作,則列印工作會在到達列印佇列頂端時自動開始列印。
提示
若要避免在新增列印工作至預設佇列時出現 [將輸出檔案儲存為] 對話框,請確定您的預設印表機不是 Microsoft XPS Document Writer、Microsoft 列印至 PDF 或其他列印到檔案選項。
/// <summary>
/// Asyncronously, add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
/// Handle the thread apartment state required by the PrintQueue.AddJob method.
/// </summary>
/// <param name="xpsFilePaths">A collection of XPS documents.</param>
/// <param name="fastCopy">Whether to validate the XPS documents.</param>
/// <returns>Whether all documents were added to the print queue.</returns>
public static async Task<bool> BatchAddToPrintQueueAsync(IEnumerable<string> xpsFilePaths, bool fastCopy = false)
{
bool allAdded = true;
// Queue some work to run on the ThreadPool.
// Wait for completion without blocking the calling thread.
await Task.Run(() =>
{
if (fastCopy)
allAdded = BatchAddToPrintQueue(xpsFilePaths, fastCopy);
else
{
// Create a thread to call the PrintQueue.AddJob method.
Thread newThread = new(() =>
{
allAdded = BatchAddToPrintQueue(xpsFilePaths, fastCopy);
});
// Set the thread to single-threaded apartment state.
newThread.SetApartmentState(ApartmentState.STA);
// Start the thread.
newThread.Start();
// Wait for thread completion. Blocks the calling thread,
// which is a ThreadPool thread.
newThread.Join();
}
});
return allAdded;
}
/// <summary>
/// Add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
/// </summary>
/// <param name="xpsFilePaths">A collection of XPS documents.</param>
/// <param name="fastCopy">Whether to validate the XPS documents.</param>
/// <returns>Whether all documents were added to the print queue.</returns>
public static bool BatchAddToPrintQueue(IEnumerable<string> xpsFilePaths, bool fastCopy)
{
bool allAdded = true;
// To print without getting the "Save Output File As" dialog, ensure
// that your default printer is not the Microsoft XPS Document Writer,
// Microsoft Print to PDF, or other print-to-file option.
// Get a reference to the default print queue.
PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
// Iterate through the document collection.
foreach (string xpsFilePath in xpsFilePaths)
{
// Get document name.
string xpsFileName = Path.GetFileName(xpsFilePath);
try
{
// The AddJob method adds a new print job for an XPS
// document into the print queue, and assigns a job name.
// Use fastCopy to skip XPS validation and progress notifications.
// If fastCopy is false, the thread that calls PrintQueue.AddJob
// must have a single-threaded apartment state.
PrintSystemJobInfo xpsPrintJob =
defaultPrintQueue.AddJob(jobName: xpsFileName, documentPath: xpsFilePath, fastCopy);
// If the queue is not paused and the printer is working, then jobs will automatically begin printing.
Debug.WriteLine($"Added {xpsFileName} to the print queue.");
}
catch (PrintJobException e)
{
allAdded = false;
Debug.WriteLine($"Failed to add {xpsFileName} to the print queue: {e.Message}\r\n{e.InnerException}");
}
}
return allAdded;
}
''' <summary>
''' Asyncronously, add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
''' Handle the thread apartment state required by the PrintQueue.AddJob method.
''' </summary>
''' <param name="xpsFilePaths">A collection of XPS documents.</param>
''' <param name="fastCopy">Whether to validate the XPS documents.</param>
''' <returns>Whether all documents were added to the print queue.</returns>
Public Shared Async Function BatchAddToPrintQueueAsync(xpsFilePaths As IEnumerable(Of String), Optional fastCopy As Boolean = False) As Task(Of Boolean)
Dim isAllPrinted As Boolean = True
' Queue some work to run on the ThreadPool.
' Wait for completion without blocking the calling thread.
Await Task.Run(
Sub()
If fastCopy Then
isAllPrinted = BatchAddToPrintQueue(xpsFilePaths, fastCopy)
Else
' Create a thread to call the PrintQueue.AddJob method.
Dim newThread As New Thread(
Sub()
isAllPrinted = BatchAddToPrintQueue(xpsFilePaths, fastCopy)
End Sub
)
' Set the thread to single-threaded apartment state.
newThread.SetApartmentState(ApartmentState.STA)
' Start the thread.
newThread.Start()
' Wait for thread completion. Blocks the calling thread,
' which is a ThreadPool thread.
newThread.Join()
End If
End Sub
)
Return isAllPrinted
End Function
''' <summary>
''' Add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
''' </summary>
''' <param name="xpsFilePaths">A collection of XPS documents.</param>
''' <param name="fastCopy">Whether to validate the XPS documents.</param>
''' <returns>Whether all documents were added to the print queue.</returns>
Public Shared Function BatchAddToPrintQueue(xpsFilePaths As IEnumerable(Of String), fastCopy As Boolean) As Boolean
Dim isAllPrinted As Boolean = True
' To print without getting the "Save Output File As" dialog, ensure
' that your default printer is not the Microsoft XPS Document Writer,
' Microsoft Print to PDF, or other print-to-file option.
' Get a reference to the default print queue.
Dim defaultPrintQueue As PrintQueue = LocalPrintServer.GetDefaultPrintQueue()
' Iterate through the document collection.
For Each xpsFilePath As String In xpsFilePaths
' Get document name.
Dim xpsFileName As String = Path.GetFileName(xpsFilePath)
Try
' The AddJob method adds a new print job for an XPS
' document into the print queue, and assigns a job name.
' Use fastCopy to skip XPS validation and progress notifications.
' If fastCopy is false, the thread that calls PrintQueue.AddJob
' must have a single-threaded apartment state.
Dim xpsPrintJob As PrintSystemJobInfo = defaultPrintQueue.AddJob(jobName:=xpsFileName, documentPath:=xpsFilePath, fastCopy)
' If the queue is not paused and the printer is working, then jobs will automatically begin printing.
Debug.WriteLine($"Added {xpsFileName} to the print queue.")
Catch e As PrintJobException
isAllPrinted = False
Debug.WriteLine($"Failed to add {xpsFileName} to the print queue: {e.Message}\r\n{e.InnerException}")
End Try
Next
Return isAllPrinted
End Function
提示
您也可以使用下列方法來列印 XPS 檔案: