【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 有效性的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/635841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04--JdbcTemplate模版

1、JdbcTemplate模版 1.1 概述 Spring JDBC Spring框架对JDBC的简单封装。提供了一个JdbcTemplate对象简化JDBC的开发&#xff08;后面专门讲spring框架) 1.2 实现步骤 1. 导入jar包 4 1 2. 创建JdbcTemplate对象。依赖于数据源DataSource JdbcTemplate template new JdbcTe…

【论文阅读 SIGMOD18】Query-based Workload Forecasting for Self-Driving

Query-based Workload Forecasting for Self-Driving Database Management Systems My Summary ABSTRACT Autonomous DBMS的第一步就是能够建模并预测工作负载&#xff0c;以前的预测技术对查询的资源利用率进行建模。然而&#xff0c;当数据库的物理设计和硬件资源发生变化…

Windows如何部署TortoiseSVN客户端

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

Spring第六天(注解开发第三方Bean)

注解开发管理第三方Bean 显然&#xff0c;我们无法在第三方Bean中写入诸如service这样的注解&#xff0c;所以&#xff0c;Spring为我们提供了Bean这一注解来让我们通过注解管理第三方Bean 第二种导入方式由于可读性太低&#xff0c;故只介绍第一种导入方式&#xff0c;这里我…

自动化工具实践操作-注入自定义代码

功能 采集掘金左边每个tab下文章的标题。人为操作就是点击一个tab&#xff0c;复制文字标题&#xff0c;重复以上操作。根据这个&#xff0c;我们可以转换成自己的代码 开始设计 如上文操作基本一致。新建任务、设计点击事件如出一辙。 自定义循环事件 操作循环节点&#…

R语言【cli】——ansi_has_any():检查字符串里是否存在ANSI格式

Package cli version 3.6.0 Usage ansi_has_any(string, sgr TRUE, csi TRUE, link TRUE) Arguments 参数【string】&#xff1a;要检查的字符串。它也可以是字符向量 参数【sgr】&#xff1a;是否查找SGR(样式化)控制序列。 参数【csi】&#xff1a;是否查找非sgr控制序…

ubuntu下常见查看库信息的指令

要查看共享库&#xff08;例如 liblog4cplus.so&#xff09;的信息&#xff0c;可以使用一些工具来获取有关库的详细信息。以下是一些常用的方法&#xff1a; 1. 使用 nm 命令&#xff1a; nm 命令用于显示目标文件或共享库的符号表。你可以运行以下命令查看 liblog4cplus.so…

Mysql:重点且常用的操作和理论知识整理 ^_^

目录 1 基础的命令操作 2 DDL 数据库定义语言 2.1 数据库操作 2.2 数据表操作 2.2.1 创建数据表 2.2.2 修改和删除数据表 2.2.3 添加外键 3 DML 数据库操作语言 3.1 插入语句(INSERT) 3.2 修改语句(UPDATE) 3.3 删除语句 3.3.1 DELETE命令 3.3.2 TRUNCATE命令 4 …

第1周:Day 3 - PyTorch与TensorFlow的异同介绍(入门级)

第1周&#xff1a;Day 3 - PyTorch介绍 学习目标 理解PyTorch的基本概念和主要特点。 成功安装PyTorch环境。 PyTorch简介 PyTorch 是一个开源的机器学习库&#xff0c;广泛用于计算机视觉和自然语言处理等领域。 它由Facebook的人工智能研究团队开发&#xff0c;提供了丰富的A…

idea中使用git提交代码报 Nothing To commit No changes detected

问题描述 在idea中右键&#xff0c;开始将变更的代码进行提交的时候&#xff0c;【Commit Directory】点击提交的时候 报 Nothing To commit No changes detected解决方案 在这里点击Test 看看是不是能下面显示git版本&#xff0c;不行的话 会显示一个 fix的字样&#xff0c;行…

【日常聊聊】边缘计算的挑战和机遇

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; 日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 边缘计算的挑战和机遇 一&#xff1a;数据安全与隐私保护 二&#xff1a;网络稳定性与可靠性 三&#xff1a;实时性与性能优…

Unity中的协程

定义&#xff1a;协程使得任务的执行可以分配到多个帧中完成&#xff0c;在Unity中&#xff0c;协程从开始执行到第一个yield return 语句后将调用权归还Unity主线程&#xff0c;并在紧随的下一帧继续从上次结束调用的代码上下文位置恢复执行。 常见应用场景&#xff1a;HTTP请…

【Vue】属性计算 computed

<script setup>import { ref,computed} from vue let hbs ref([]); //装爱好的值const publishHbsMessagecomputed(()>{return hbs.value.length>0?Yes:No}) </script><template><div>吃 <input type"checkbox" name"hbs&qu…

C++入门学习(八)sizeof关键字

sizeof 是 C 和 C 中的一个运算符&#xff0c;用于确定特定类型或对象的内存大小&#xff08;以字节为单位&#xff09;。 1、查看数据类型占据内存大小 #include <iostream> using namespace std; int main() {short a 1;int b 1;long c 1;long long d 1;cout<…

Ubuntu使用docker-compose安装chatGPT

ubuntu环境搭建专栏&#x1f517;点击跳转 Ubuntu系统环境搭建&#xff08;十五&#xff09;——使用docker-compose安装chatGPT Welcome to the AI era! 使用docker compose安装 在/usr/local文件夹下创建chatgpt mkdir chatgpt创建docker-compose.yaml vim docker-compos…

代码随想录算法训练营Day32|122.买卖股票的最佳时机 II、55. 跳跃游戏、45.跳跃游戏 II

目录 122.买卖股票的最佳时机 II 前言 思路 算法实现 55. 跳跃游戏 思路 算法实现 45.跳跃游戏 II 前言 思路 算法实现 总结 122.买卖股票的最佳时机 II 题目链接 文章链接 前言 本题要求只能持有一支股票&#xff0c;根据每日股票的价格控制股票的买入和卖出获取最…

6. UE5 RPG AttributeSet的设置

AttributeSet 负责定义和持有属性并且管理属性的变化。开发者可以子类化UAttributeSet。在OwnerActor的构造方法中创建的AttributeSet将会自动注册到ASC。这一步必须在C中完成。 Attributes 是由 FGameplayAttributeData定义的浮点值。 Attributes能够表达从角色的生命值到角色…

文件扫码下载的方法?轻松制作文件活码的技巧

现在多文件生成二维码的需求不断的增多&#xff0c;为什么大家都开始选择这种方式来展示文件呢&#xff1f;一方面是将文件储存在云端&#xff0c;避免有时间限制的问题&#xff0c;随时查看文件&#xff1b;二是可以让其他人同时扫描二维码查看内容&#xff0c;当需要分享给很…

Vue四个阶段,八个钩子函数

- 创造阶段&#xff1a;创建Vue实例和初始化数据事件&#xff0c;数据代理&#xff0c;监测watch - beforeCreate&#xff0c;只是创建实例&#xff0c;不能this.$el,this.msg,this.方法名&#xff08;&#xff09; - created&#xff0c;数据代理了&#xff0c;能v…

内网部署,移动端如何使用,且保障电脑端安全

A. 在企业内网自建DNS服务&#xff0c;然后使用域名代替公网IP重新配置&#xff1b; B. 在互联网区域&#xff0c;使用互联网DNS服务将域名解析到公网IP&#xff1b; C. 在内网区域&#xff0c;使用自建DNS服务将域名解析到服务器内网IP&#xff0c;这样内网电脑不能联网也能正…