Как распечатать файл XPS (WPF .NET)
Иногда необходимо добавить новое задание печати в очередь печати без открытия диалогового окна печати. Для этого можно использовать один из методов PrintQueue.AddJob. Вот как.
В следующем примере мы используем метод AddJob(String, String, Boolean), один из нескольких перегрузок AddJob
, чтобы:
- Добавьте новое задание печати для документа XML Paper Specification (XPS) в очередь печати по умолчанию.
- Назовите новое задание.
- Укажите, следует ли проверять документ XPS (с помощью параметра
fastCopy
).
При использовании метода AddJob(String, String, Boolean)
значение параметра fastCopy
является ключевым фактором:
- Если для параметра
fastCopy
задано значениеtrue
, проверка XPS будет пропущена, а задание печати быстро загрузится без обратной связи о прогрессе по страницам. - Если для параметра
fastCopy
задано значениеfalse
, поток, вызывающий методAddJob
, должен иметь состояние однопоточной квартиры, в противном случае будет выброшено исключение. Дополнительные сведения см. в разделе Примечания для AddJob(String, String, Boolean).
Добавление новых заданий печати в очередь
В этом примере в очередь по умолчанию добавляется один или несколько документов XPS. Код будет:
- Используйте Task.Run, чтобы избежать блокировки потока пользовательского интерфейса, так как нет асинхронной версии
AddJob
. - Если значение параметра
fastCopy
равноfalse
, выполните AddJob(String, String, Boolean) в потоке, находящемся в состоянии однопоточной квартиры с . - Получите ссылку на PrintQueue по умолчанию для LocalPrintServer.
- Выполните вызов
AddJob(String, String, Boolean)
в очереди печати, передав имя задания, путь к документу XPS и параметрfastCopy
.
Если очередь не приостановлена и принтер работает, задание печати автоматически начнет печать, когда она достигнет верхней части очереди печати.
Совет
Чтобы избежать диалогового окна Сохранить выходной файл как при добавлении задания на печать в очередь по умолчанию, убедитесь, что принтер по умолчанию не Microsoft XPS Document Writer, Microsoft Print to 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 с помощью:
- методы PrintDialog.PrintDocument или PrintDialog.PrintVisual.
- методы XpsDocumentWriter.Write и XpsDocumentWriter.WriteAsync.
Дополнительные сведения см. в разделе Как отображать диалоговое окно печати и Обзор печати документов.
См. также
.NET Desktop feedback