Monday, January 4, 2010

Converting XPS to PDF Programmatically

I am working on a simple utility tool which pulls data from database and then generates reports as E-Mail attachments. An additional requirement is to exam the reports before sending them out. Hence, I want a document format that meets these criteria.

  • Easy to generate;
  • Can be review in Win Form program;
  • Widely support by client computers.

Using WPF, XPS is the best choice for first two requirements. Precisely, generating a FlowDocument is as simple as writing HTML, and XSLT can translate any XML data into XPS flow document. On the other side, FixedDocument provides the same feel as a print out.

However, XPS requires a viewer installed. Some of our recipients may not have the privilege to install the viewer. So I would like to send out a PDF instead of XPS.

Converting FlowDocument to FixedDocument

In order to review the exact same documents as the ones sending out. We need to first convert the flow document to fixed document. A easy way is simply save the flow document by setting it"s page size.

var source = (IDocumentPaginatorSource)flowDoc;
var paginator = source.DocumentPaginator;

// Letter size
paginator.PageSize = new Size(8.5 * 96, 11 * 96);

using (XpsDocument doc = new XpsDocument(tempXpsPath, FileAccess.Write))
    var writer = XpsDocument.CreateXpsDocumentWriter(doc);

Now, use a DocumentViewer to display it in WPF. Here is the result:
XPS Viewer

If you would like to do it in memory, Here is an article from Tamir Khason. But I will need the temprary XPS files for next step anyway.

Converting XPS to PDF

This part is much more challenging. I would like to do a trick to get my PDFs, rather than read through the XPS/PDF specifications. I am using GhostPCL to convert XPS to PDF. Download and build GhostXPS following the instruction, then copy gxps.exe (under xps/obj folder) to our project.

Now, we may call gxps to convert the temporary XPS to PDF.

// Convert XPS to PDF using gxps
ProcessStartInfo gxpsArguments = new ProcessStartInfo("gxps.exe", String.Format("-sDEVICE=pdfwrite -sOutputFile={0} -dNOPAUSE {1}", path, tempXpsPath));
gxpsArguments.WindowStyle = ProcessWindowStyle.Hidden;
using (var gxps = Process.Start(gxpsArguments))

The sample program can be download here. Hope this help!


Cassie said...

Thanks for the download link, and for the mini tutorial :) I appreciate it..

xps to pdf

M.Shawn said...

While exporting XPS to PDF we are also looking for export of the xps document outline into the pdf bookmarks. Unfotunately NiXPS does not support that.

xps to pdf

Post a Comment