在本系列的第一篇文章中,提到了在寻找生成XPS文档的优质资源时遇到的问题,但当时只涵盖了XPS的结构。现在,将介绍一种生成XPS文档的方法,重点是使用.NET Framework中的API。
尽管这篇文章来得有点晚,而且篇幅不长,但它并非完全没有用处。希望它能提供一些有用的指导。在这一点上,应该感谢Bob Watson的文章《XPS文档:创建XMLPaper Specification文档的API初探》;本文中的许多代码都是从他的文章中借鉴而来的。
这是一个简单的控制台应用程序。一旦执行,它将创建一个名为"HelloWorld.xps"的文档。它还做了一些假设,例如,它假设可以在"C:\Windows\Fonts"位置找到"arial.ttf"字体文件。请进行必要的更改以使其工作。
首先,需要访问XPS API。为此,需要添加对ReachFramework.dll的引用。然而,它实际上需要引用WindowsBase.dll来进行zip文件的工作。换句话说,需要同时引用这两个DLL。在代码中,还需要添加一个using语句,用于System.Windows.Xps.Packaging。
首先,打开一个新的XPS文档。下面是一个示例:
#region The setup - Creating all the objects needed
//
Create the new document
XpsDocument xd =
new
XpsDocument(
"
HelloWorld.xps"
, FileAccess.ReadWrite);
//
Create a new FixedDocumentSequence object in the document
IXpsFixedDocumentSequenceWriter xdSW = xd.AddFixedDocumentSequence();
//
Create a new FixedDocument object in in the document sequence
IXpsFixedDocumentWriter xdW = xdSW.AddFixedDocument();
//
Add a new FixedPage to the FixedDocument
IXpsFixedPageWriter xpW = xdW.AddFixedPage();
//
Add a Font to the FixedPage and get back where it ended up
string
fontURI = AddFontResourceToFixedPage(xpW,
"
C:\\Windows\\Fonts\\Arial.ttf"
);
StringBuilder pageContents =
new
StringBuilder();
#endregion
可以看到上面的命令中的XPS文档的层次结构。文档 -> 固定文档序列 -> 固定文档 -> 固定页面。记住这个层次结构,当操作XPS文档时会更容易。
这部分,只是将XPS构建为一个字符串。然而,也可以将XAML展平;参见上面提到的Bob的文章参考,了解如何做到这一点。当然,另一种方式是生成XPS(XML),有很多方法可以做到这一点。
#region The actual XPS markup
//
Try changing the Width and Height and see what you get
pageContents.AppendLine(
"
"
);
pageContents.AppendLine(
"
"
);
pageContents.AppendLine(
"
"
);
#endregion
这就是能创建的最简单的XPS文档。没有使用Indices属性,以保持事情的简单性。将注意到fontURI来自前一节中函数调用的返回值。
最后一部分是完成所有对象;通过让它们提交,确保zip文件中的各种元素都正确完成。
#region The shutdown - Commiting all of the objects
//
Write the XPS markup out to the page
XmlWriter xmlWriter = xpW.XmlWriter;
xmlWriter.WriteRaw(pageContents.ToString());
//
Commit the page
xpW.Commit();
//
Close the XML writer
xmlWriter.Close();
//
Commit the fixed document
xdW.Commit();
//
Commite the fixed document sequence writer
xdSW.Commit();
//
Commit the XPS document itself
xd.Close();
#endregion
就是这样。正如注释中建议的,尝试玩一下实际的XPS标记,看看它会生成什么。可能需要在每次运行之间删除XPS(特别是如果出了什么问题)。尝试添加更多资源、页面和文档;也可以尝试混淆字体文件,看看会得到什么。但为此,需要实际查看代码,看看该怎么做。