且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

wpf中xps文档合并功能实现

更新时间:2022-09-17 19:56:54

原文:wpf中xps文档合并功能实现

     跟着上一篇的xps文档套打的文章,近期一直在研究xps打印技术,其中用户提到了一个需求,要求能够多页面进行打印,我的想法是,先生成xps文件,然后将文件读取出来以后,合并成一个文件来处理。

      如果要是直接先打开一个xps文件,用新文件去写FixedDocument,或者DocumentSequence ,添加到新的文件中的话,会报错,提示,

“System.Windows.Xps.XpsPackagingException”类型的未经处理的异常在 ReachFramework.dll 中发生其他信息: Package 已经有根 DocumentSequence 或 FixedDocument。“

    如果你要是直接写元素的话,则出现如下提示:

”System.InvalidOperationException”类型的未经处理的异常在 PresentationFramework.dll 中发生其他信息: 指定的元素已经是另一个元素的逻辑子元素。请先将其断开连接。“

通过研究微软的一个例子,终于搞定:

如果您技术超强,可以直接去看微软的例子,那个上面定义了5个类,有预览、显示、文件拖动,异步读取等等,非常的全的确是一个好例子,也比较适合于学习如何定义类,但是很容易被里面的东西给绕晕了,我比照的这个例子自己写了一个简单的合并文件的函数,可以比较直观的了解xps的结构,复制的情况。

上代码:

 1   private void Button_Click(object sender, RoutedEventArgs e)
 2         {
 3                MergeDocument();
 4            
 5         }
 6 
 7         //完全不使用类,函数方式
 8         public void MergeDocument()
 9         {
10 
11             string fristFile = "test1.xps";
12             string secoFile = "test2.xps";
13 
14             string newFile = "xpsShow.xps";
15             File.Delete(newFile);
16 
17          
18             FixedDocumentSequence newFds = new FixedDocumentSequence();//创建一个新的文档结构
19 
20             DocumentReference newDocRef = AddPage(fristFile);//加入第一个文件
21             newFds.References.Add(newDocRef);
22 
23             newDocRef = AddPage(secoFile);
24             newFds.References.Add(newDocRef);//加入第二个文件
25 
26             //xps写入新文件
27             XpsDocument NewXpsDocument = new XpsDocument(newFile, System.IO.FileAccess.ReadWrite);
28             XpsDocumentWriter xpsDocumentWriter = XpsDocument.CreateXpsDocumentWriter(NewXpsDocument);
29             xpsDocumentWriter.Write(newFds);
30             NewXpsDocument.Close();
31 
32             //读取并显示
33             XpsDocument xpsnewDocument = new XpsDocument(newFile, FileAccess.Read);
34             docView.Document = xpsnewDocument.GetFixedDocumentSequence();
35         }
36 
37         public DocumentReference AddPage(string fileName)
38         {
39             DocumentReference newDocRef = new DocumentReference();
40             FixedDocument newFd = new FixedDocument();
41 
42             XpsDocument xpsDocument = new XpsDocument(fileName, FileAccess.Read);
43             FixedDocumentSequence docSeq = xpsDocument.GetFixedDocumentSequence();
44 
45             foreach (DocumentReference docRef in docSeq.References)
46             {
47                 FixedDocument fd = docRef.GetDocument(false);
48 
49                 foreach (PageContent oldPC in fd.Pages)
50                 {
51                     Uri uSource = oldPC.Source;//读取源地址
52                     Uri uBase = (oldPC as IUriContext).BaseUri;//读取目标页面地址
53 
54                     PageContent newPageContent = new PageContent();
55                     newPageContent.GetPageRoot(false);//这个地方应当是把文档解压成一个包放到内存中我们再去读取
56                     newPageContent.Source = uSource;
57                     (newPageContent as IUriContext).BaseUri = uBase;
58                     newFd.Pages.Add(newPageContent);//将新文档追加到新的documentRefences中
59                 }
60             }
61             newDocRef.SetDocument(newFd);
62             xpsDocument.Close();
63             return newDocRef;
64         }

在这个例子中,xps文档是通过页面的方式直接读取了以后复制的。

xps文档真是一个好东西,我个人认为,我们完全可以将xps文档做成一个简单的报表打印工具,尤其适合哪种用户要求格式严格、数据项目比较多,打印要求不能有锯齿的表格打印(计算不是他的强项)。

源代码下载:http://download.csdn.net/detail/bcc222/6557311