Click here to Skip to main content
15,861,125 members
Articles / Desktop Programming / WPF

Hello XPS World - Part 2 of n (of too many)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
2 Aug 2008CPOL3 min read 61K   1.3K   19   10
Well, somebody had to do it.

Contents

Introduction

In the first article in this series, I referred to the problems I found in finding good sources to generate XPS with - but I only covered the XPS structure in that article. So finally, here's a small taste of one way to generate XPS documents, focusing on using the API in the .NET Framework.

Background

It's been a little long coming this article, especially considering how short it is. Inspite of the fact that it's a "Hello World" application, it's not completely useless. I hope it will provide some good pointers.

At this point, I definitely should give credit to Bob Watson's article: "XPS Documents: A First Look at APIs For Creating XML Paper Specification Documents"; much of the code in this project is plagiarised from his article.

Using the Code

This is yet another simple console application. Once executed, it creates the document "HelloWorld.xps". It also makes a few assumptions, for instance, that it can find the arial.ttf font file at the location C:\Windows\Fonts. Please make the necessary changes to get it working.

First of all, what do you need to get at the XPS APIs? For that, add a reference to ReachFramework.dll. However, it effectively needs to reference WindowsBase.dll for the zip file work that it does. In other words, you'll need to reference to both DLLs. Within your code, you'll also need to add a using statement for System.Windows.Xps.Packaging.

So first off, there's cracking open a new XPS document. Here's an example:

C#
#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();

// Ccreate 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

You can plainly see the hierarchy of an XPS document in the above commands. Document -> Fixed Document Sequence -> Fixed Document -> Fixed Page. Keeping that hierarchy in mind makes it easier when manipulating XPS documents.

Next is creating the actual XPS itself. For this part, I've just built the XPS as a string. However, you can also take XAML and flatten it out; see Bob's article reference above for an example of this. Yet another way, of course, is to generate the XPS (XML), and there's plenty of ways of doing this.

C#
#region The actual XPS markup
// Try changing the Width and Height and see what you get
pageContents.AppendLine("<FixedPage Width=\"793.76\" Height=\"1122.56\"
 xmlns=\"http://schemas.microsoft.com/xps/2005/06\" xml:lang=\"und\">");
pageContents.AppendLine("<Glyphs Fill=\"#ff000000\" FontRenderingEmSize=\"16\"
 StyleSimulations=\"None\" OriginX=\"75.68\" OriginY=\"90.56\"");
// Add the fontURI
pageContents.AppendFormat(" FontUri=\"{0}\" ", fontURI);
// HERE IT IS
pageContents.AppendLine("  UnicodeString=\"Hello XPS World!\"/>");
pageContents.AppendLine("</FixedPage>");
#endregion

It's about the briefest that I could get an XPS document. I've not bothered with the Indices attribute to keep things even simpler. You'll note that the fontURI comes from the return of the function call in the previous section.

The last part is finishing with all of the objects; by getting them to commit, we ensure that the various elements in the zip file get all completed correctly.

C#
#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

And that's it. As suggested in the comments, do some playing around with some of the actual XPS markup and see what it generates. You may find that you need to delete the XPS between each run though (especially if something screws up). Try adding more resources, pages, and documents; also, try obfuscating the font files and see what you get. But for that, you'll need to actually look at the code to see what to do.

Other Parts

History

  • 2008-09-03: First version completed.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder md8n
Timor-Leste Timor-Leste
If it ain't broke - that can be arranged.

Comments and Discussions

 
QuestionCan we convert MS office document to XPS ? Pin
Sivaji156526-Aug-15 1:15
Sivaji156526-Aug-15 1:15 
AnswerRe: Can we convert MS office document to XPS ? Pin
Lee Humphries26-Aug-15 12:21
professionalLee Humphries26-Aug-15 12:21 
QuestionHow to avoid fonts added repetitively Pin
JunHaoShih23-Jul-15 16:18
JunHaoShih23-Jul-15 16:18 
AnswerRe: How to avoid fonts added repetitively Pin
Lee Humphries26-Aug-15 12:12
professionalLee Humphries26-Aug-15 12:12 
QuestionRight align Text Pin
prakash_dale3-Jan-15 23:52
prakash_dale3-Jan-15 23:52 
GeneralRe: Right align Text Pin
prakash_dale4-Jan-15 0:09
prakash_dale4-Jan-15 0:09 
GeneralHow to do Centering without processing the Font. Pin
Lee Humphries4-Jan-15 12:58
professionalLee Humphries4-Jan-15 12:58 
QuestionHow to add multiple fpages to fixeddocument? Pin
mohammed safiq16-Jun-13 20:09
mohammed safiq16-Jun-13 20:09 
AnswerRe: How to add multiple fpages to fixeddocument? Pin
Lee Humphries16-Jun-13 20:38
professionalLee Humphries16-Jun-13 20:38 
Have you read the other article on XPS that I wrote?
In that I covered the XPS structure.

Here's one way to 'discover' the structure that you'll need:
Create a multi page document in your favourite editor.
'Print' it using the XPS printer driver.
Rename the 'print' file from .xps to .zip
Unpack the contents and use information from my previous article to help determine how to build and add multiple pages.

Never attribute to malice that which can be adequately explained by stupidity.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.