【WPF.NET开发】以编程方式打印XPS文件

2024-01-20 14:52

本文主要是介绍【WPF.NET开发】以编程方式打印XPS文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文内容

可以使用 AddJob 方法的一个重载来打印 XML 纸张规范 (XPS) 文件,而根本无需打开 PrintDialog 或任何用户界面 (UI)(从原理上讲)。

还还可以使用多种 XpsDocumentWriter.Write 和 XpsDocumentWriter.WriteAsync 方法打印 XPS 文件。 

打印 XPS 的另一种方法是使用 PrintDialog.PrintDocument 或 PrintDialog.PrintVisual 方法。 

示例

使用三参数 AddJob(String, String, Boolean) 方法的主要步骤如下。 以下示例提供了详细信息。

  1. 确定打印机是否是 XPSDrv 打印机。 

  2. 如果打印机不是 XPSDrv 打印机,将线程的单元设置为单线程。

  3. 实例化打印服务器并打印队列对象。

  4. 调用该方法,指定作业的名称、要打印的文件和一个 Boolean 标志,该标志指示该打印机是否是 XPSDrv 打印机。

以下示例演示如何以批处理方式打印目录中的所有 XPS 文件。 尽管应用程序会提示用户指定目录,但三参数 AddJob(String, String, Boolean) 方法不需要用户界面 (UI)。 它可用于具有 XPS 文件名的任何代码路径和可以传递到该方法的路径。

只要 Boolean 参数为 false(使用非 XPSDrv 打印机时,该参数必须为此值),AddJob 的三参数 AddJob(String, String, Boolean) 重载必须在单线程单元中运行。 但是,.NET 的默认单元状态为多线程。 由于本示例假定使用非 XPSDrv 打印机,因此此默认值必须为相反值。

有两种可用于更改此默认值的方法。 一种方法是在应用程序的 Main 方法(通常为“static void Main(string[] args)”)的第一行正上方添加 STAThreadAttribute(即“[System.STAThreadAttribute()]”)即可。 但是,许多应用程序要求 Main 方法具有多线程单元状态,因此存在第二种方法:将对 AddJob(String, String, Boolean) 的调用放在单独的线程中,该线程的单元状态通过 SetApartmentState 设置为 STA。 以下示例使用第二种方法。

因此,该示例先实例化 Thread 对象,并向其传递 PrintXPS 方法,以用作 ThreadStart 参数。 (该示例的后面部分定义了 PrintXPS 方法。)接下来,将线程设置为单线程单元。 Main 方法的唯一剩余代码会启动新线程。

该示例的内容主要关于 staticBatchXPSPrinter.PrintXPS 方法。 创建打印服务器和队列后,该方法会提示用户提供包含 XPS 文件的目录。 在验证存在该目录且其中存在 *.xps 文件之后,该方法会将每个此类文件添加到打印队列。 该示例假定打印机不是 XPSDrv 打印机,因此将向 AddJob(String, String, Boolean) 方法的最后一个参数传递 false。 出于此原因,该方法先验证文件中的 XPS 标记,然后再尝试将其转换为打印机的页面描述语言。 如果验证失败,会引发异常。 该示例代码将捕获该异常,并通知用户相关信息,然后继续处理下一 XPS 文件。

class Program
{[System.MTAThreadAttribute()] // Added for clarity, but this line is redundant because MTA is the default.static void Main(string[] args){// Create the secondary thread and pass the printing method for// the constructor's ThreadStart delegate parameter. The BatchXPSPrinter// class is defined below.Thread printingThread = new Thread(BatchXPSPrinter.PrintXPS);// Set the thread that will use PrintQueue.AddJob to single threading.printingThread.SetApartmentState(ApartmentState.STA);// Start the printing thread. The method passed to the Thread// constructor will execute.printingThread.Start();}//end Main
}//end Program classpublic class BatchXPSPrinter
{public static void PrintXPS(){// Create print server and print queue.LocalPrintServer localPrintServer = new LocalPrintServer();PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();// Prompt user to identify the directory, and then create the directory object.Console.Write("Enter the directory containing the XPS files: ");String directoryPath = Console.ReadLine();DirectoryInfo dir = new DirectoryInfo(directoryPath);// If the user mistyped, end the thread and return to the Main thread.if (!dir.Exists){Console.WriteLine("There is no such directory.");}else{// If there are no XPS files in the directory, end the thread// and return to the Main thread.if (dir.GetFiles("*.xps").Length == 0){Console.WriteLine("There are no XPS files in the directory.");}else{Console.WriteLine("\nJobs will now be added to the print queue.");Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.");// Batch process all XPS files in the directory.foreach (FileInfo f in dir.GetFiles("*.xps")){String nextFile = directoryPath + "\\" + f.Name;Console.WriteLine("Adding {0} to queue.", nextFile);try{// Print the Xps file while providing XPS validation and progress notifications.PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob(f.Name, nextFile, false);}catch (PrintJobException e){Console.WriteLine("\n\t{0} could not be added to the print queue.", f.Name);if (e.InnerException.Message == "File contains corrupted data."){Console.WriteLine("\tIt is not a valid XPS file. Use the isXPS Conformance Tool to debug it.");}Console.WriteLine("\tContinuing with next XPS file.\n");}}// end for each XPS file}//end if there are no XPS files in the directory}//end if the directory does not existConsole.WriteLine("Press Enter to end program.");Console.ReadLine();}// end PrintXPS method
}// end BatchXPSPrinter class

如果使用 XPSDrv 打印机,则可将最后一个参数设置为 true。 在这种情况下,由于 XPS 是打印机的页面描述语言,该方法会将文件发送到打印机,而不会对其进行验证或将其转换为另一种页面描述语言。 如果在设计时不确定应用程序是否会使用 XPSDrv 打印机,可以修改应用程序,使其根据所发现的内容读取 IsXpsDevice 属性和分支。

由于发布 Windows Vista 和 Microsoft .NET Framework 后,最初存在几个可立即使用的 XPSDrv 打印机,可能需要将非 XPSDrv 打印机伪装为 XPSDrv 打印机。 为此,请将 Pipelineconfig.xml 添加到运行应用程序的计算机的注册表项中的以下文件列表:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\<PseudoXPSPrinter>\DependentFiles

其中 <PseudoXPSPrinter> 是任一打印队列。 然后必须重新启动计算机。

此伪装允许用户将 true 传递为 AddJob(String, String, Boolean) 的最后一个参数,而不会引发异常,但由于 <PseudoXPSPrinter> 并不是真正的 XPSDrv 打印机,所以仅会打印垃圾内容。

 备注

为简单起见,以上示例通过测试是否存在 *.xps 扩展名来确定文件是否为 XPS。 但是,XPS 文件不需要具有此扩展名。 isXPS.exe(isXPS 合规性工具)是一种测试文件是否具有 XPS 有效性的方法。

这篇关于【WPF.NET开发】以编程方式打印XPS文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/626371

相关文章

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

Mybatis的分页实现方式

《Mybatis的分页实现方式》MyBatis的分页实现方式主要有以下几种,每种方式适用于不同的场景,且在性能、灵活性和代码侵入性上有所差异,对Mybatis的分页实现方式感兴趣的朋友一起看看吧... 目录​1. 原生 SQL 分页(物理分页)​​2. RowBounds 分页(逻辑分页)​​3. Page

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

Python程序打包exe,单文件和多文件方式

《Python程序打包exe,单文件和多文件方式》:本文主要介绍Python程序打包exe,单文件和多文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python 脚本打成exe文件安装Pyinstaller准备一个ico图标打包方式一(适用于文件较少的程