I recently had the need to convert Word, Excel, and PowerPoint files to Microsoft’s XPS format for easy displaying in WPF. There’s a plethora of articles, threads, and questions out there that illustrate how to do this, but I haven’t seen anyone compile a single class/library that will convert from all three applications with good error handling and no price tag.
So I figured since I had to write it anyway I’d post it here for the aid of anyone else looking to do the same thing. As always comments/questions/praise are appreciated.
using System; using System.Collections.Generic; using System.IO; using Excel = Microsoft.Office.Interop.Excel; using PowerPoint = Microsoft.Office.Interop.PowerPoint; using Word = Microsoft.Office.Interop.Word; namespace CGS { public class OfficeToXps { #region Properties & Constants private static List<string> wordExtensions = new List<string> { ".doc", ".docx" }; private static List<string> excelExtensions = new List<string> { ".xls", ".xlsx" }; private static List<string> powerpointExtensions = new List<string> { ".ppt", ".pptx" }; #endregion #region Public Methods public static OfficeToXpsConversionResult ConvertToXps(string sourceFilePath, ref string resultFilePath) { var result = new OfficeToXpsConversionResult(ConversionResult.UnexpectedError); // Check to see if it's a valid file if (!IsValidFilePath(sourceFilePath)) { result.Result = ConversionResult.InvalidFilePath; result.ResultText = sourceFilePath; return result; } var ext = Path.GetExtension(sourceFilePath).ToLower(); // Check to see if it's in our list of convertable extensions if (!IsConvertableFilePath(sourceFilePath)) { result.Result = ConversionResult.InvalidFileExtension; result.ResultText = ext; return result; } // Convert if Word if (wordExtensions.Contains(ext)) { return ConvertFromWord(sourceFilePath, ref resultFilePath); } // Convert if Excel if (excelExtensions.Contains(ext)) { return ConvertFromExcel(sourceFilePath, ref resultFilePath); } // Convert if PowerPoint if (powerpointExtensions.Contains(ext)) { return ConvertFromPowerPoint(sourceFilePath, ref resultFilePath); } return result; } #endregion #region Private Methods public static bool IsValidFilePath(string sourceFilePath) { if (string.IsNullOrEmpty(sourceFilePath)) return false; try { return File.Exists(sourceFilePath); } catch (Exception) { } return false; } public static bool IsConvertableFilePath(string sourceFilePath) { var ext = Path.GetExtension(sourceFilePath).ToLower(); return IsConvertableExtension(ext); } public static bool IsConvertableExtension(string extension) { return wordExtensions.Contains(extension) || excelExtensions.Contains(extension) || powerpointExtensions.Contains(extension); } private static string GetTempXpsFilePath() { return Path.ChangeExtension(Path.GetTempFileName(), ".xps"); } private static OfficeToXpsConversionResult ConvertFromWord(string sourceFilePath, ref string resultFilePath) { object pSourceDocPath = sourceFilePath; string pExportFilePath = string.IsNullOrWhiteSpace(resultFilePath) ? GetTempXpsFilePath() : resultFilePath; try { var pExportFormat = Word.WdExportFormat.wdExportFormatXPS; bool pOpenAfterExport = false; var pExportOptimizeFor = Word.WdExportOptimizeFor.wdExportOptimizeForOnScreen; var pExportRange = Word.WdExportRange.wdExportAllDocument; int pStartPage = 0; int pEndPage = 0; var pExportItem = Word.WdExportItem.wdExportDocumentContent; var pIncludeDocProps = true; var pKeepIRM = true; var pCreateBookmarks = Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks; var pDocStructureTags = true; var pBitmapMissingFonts = true; var pUseISO19005_1 = false; Word.Application wordApplication = null; Word.Document wordDocument = null; try { wordApplication = new Word.Application(); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToInitializeOfficeApp, "Word", exc); } try { try { wordDocument = wordApplication.Documents.Open(ref pSourceDocPath); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToOpenOfficeFile, exc.Message, exc); } if (wordDocument != null) { try { wordDocument.ExportAsFixedFormat( pExportFilePath, pExportFormat, pOpenAfterExport, pExportOptimizeFor, pExportRange, pStartPage, pEndPage, pExportItem, pIncludeDocProps, pKeepIRM, pCreateBookmarks, pDocStructureTags, pBitmapMissingFonts, pUseISO19005_1 ); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToExportToXps, "Word", exc); } } else { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToOpenOfficeFile); } } finally { // Close and release the Document object. if (wordDocument != null) { wordDocument.Close(); wordDocument = null; } // Quit Word and release the ApplicationClass object. if (wordApplication != null) { wordApplication.Quit(); wordApplication = null; } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); } } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToAccessOfficeInterop, "Word", exc); } resultFilePath = pExportFilePath; return new OfficeToXpsConversionResult(ConversionResult.OK, pExportFilePath); } private static OfficeToXpsConversionResult ConvertFromPowerPoint(string sourceFilePath, ref string resultFilePath) { string pSourceDocPath = sourceFilePath; string pExportFilePath = string.IsNullOrWhiteSpace(resultFilePath) ? GetTempXpsFilePath() : resultFilePath; try { PowerPoint.Application pptApplication = null; PowerPoint.Presentation pptPresentation = null; try { pptApplication = new PowerPoint.Application(); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToInitializeOfficeApp, "PowerPoint", exc); } try { try { pptPresentation = pptApplication.Presentations.Open(pSourceDocPath, Microsoft.Office.Core.MsoTriState.msoTrue, Microsoft.Office.Core.MsoTriState.msoTrue, Microsoft.Office.Core.MsoTriState.msoFalse); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToOpenOfficeFile, exc.Message, exc); } if (pptPresentation != null) { try { pptPresentation.ExportAsFixedFormat( pExportFilePath, PowerPoint.PpFixedFormatType.ppFixedFormatTypeXPS, PowerPoint.PpFixedFormatIntent.ppFixedFormatIntentScreen, Microsoft.Office.Core.MsoTriState.msoFalse, PowerPoint.PpPrintHandoutOrder.ppPrintHandoutVerticalFirst, PowerPoint.PpPrintOutputType.ppPrintOutputSlides, Microsoft.Office.Core.MsoTriState.msoFalse, null, PowerPoint.PpPrintRangeType.ppPrintAll, string.Empty, true, true, true, true, false ); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToExportToXps, "PowerPoint", exc); } } else { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToOpenOfficeFile); } } finally { // Close and release the Document object. if (pptPresentation != null) { pptPresentation.Close(); pptPresentation = null; } // Quit Word and release the ApplicationClass object. if (pptApplication != null) { pptApplication.Quit(); pptApplication = null; } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); } } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToAccessOfficeInterop, "PowerPoint", exc); } resultFilePath = pExportFilePath; return new OfficeToXpsConversionResult(ConversionResult.OK, pExportFilePath); } private static OfficeToXpsConversionResult ConvertFromExcel(string sourceFilePath, ref string resultFilePath) { string pSourceDocPath = sourceFilePath; string pExportFilePath = string.IsNullOrWhiteSpace(resultFilePath) ? GetTempXpsFilePath() : resultFilePath; try { var pExportFormat = Excel.XlFixedFormatType.xlTypeXPS; var pExportQuality = Excel.XlFixedFormatQuality.xlQualityStandard; var pOpenAfterPublish = false; var pIncludeDocProps = true; var pIgnorePrintAreas = true; Excel.Application excelApplication = null; Excel.Workbook excelWorkbook = null; try { excelApplication = new Excel.Application(); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToInitializeOfficeApp, "Excel", exc); } try { try { excelWorkbook = excelApplication.Workbooks.Open(pSourceDocPath); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToOpenOfficeFile, exc.Message, exc); } if (excelWorkbook != null) { try { excelWorkbook.ExportAsFixedFormat( pExportFormat, pExportFilePath, pExportQuality, pIncludeDocProps, pIgnorePrintAreas, OpenAfterPublish : pOpenAfterPublish ); } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToExportToXps, "Excel", exc); } } else { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToOpenOfficeFile); } } finally { // Close and release the Document object. if (excelWorkbook != null) { excelWorkbook.Close(); excelWorkbook = null; } // Quit Word and release the ApplicationClass object. if (excelApplication != null) { excelApplication.Quit(); excelApplication = null; } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); } } catch (Exception exc) { return new OfficeToXpsConversionResult(ConversionResult.ErrorUnableToAccessOfficeInterop, "Excel", exc); } resultFilePath = pExportFilePath; return new OfficeToXpsConversionResult(ConversionResult.OK, pExportFilePath); } #endregion } public class OfficeToXpsConversionResult { #region Properties public ConversionResult Result { get; set; } public string ResultText { get; set; } public Exception ResultError { get; set; } #endregion #region Constructors public OfficeToXpsConversionResult() { Result = ConversionResult.UnexpectedError; ResultText = string.Empty; } public OfficeToXpsConversionResult(ConversionResult result) : this() { Result = result; } public OfficeToXpsConversionResult(ConversionResult result, string resultText) : this(result) { ResultText = resultText; } public OfficeToXpsConversionResult(ConversionResult result, string resultText, Exception exc) : this(result, resultText) { ResultError = exc; } #endregion } public enum ConversionResult { OK = 0, InvalidFilePath = 1, InvalidFileExtension = 2, UnexpectedError = 3, ErrorUnableToInitializeOfficeApp = 4, ErrorUnableToOpenOfficeFile = 5, ErrorUnableToAccessOfficeInterop = 6, ErrorUnableToExportToXps = 7 } } |
This solution uses the 2007 Office Interop libraries for Word, Excel, and PowerPoint. To compile it in Visual Studio you’ll need to reference these assemblies in your project. For example here’s what the Word assembly looks like:

Also note that I’ve made use of some shortcuts provided by the new optional parameters in C# 4.0. If you’re using an earlier version of .Net you’ll have to make some changes to the interop calls, but it’s nothing serious.
Here’s a quick example of using the given code in an application:
string filePath = @"C:\Test\Test.doc"; string xpsFilePath = @"C:\Test\Test.xps"; var convertResults = OfficeToXps.ConvertToXps(filePath, ref xpsFilePath); switch (convertResults.Result) { case ConversionResult.OK: XpsDocument xpsDoc = new XpsDocument(xpsFilePath, FileAccess.ReadWrite); break; case ConversionResult.InvalidFilePath: // Handle bad file path or file missing break; case ConversionResult.UnexpectedError: // This should only happen if the code is modified poorly break; case ConversionResult.ErrorUnableToInitializeOfficeApp: // Handle Office 2007 (Word | Excel | PowerPoint) not installed break; case ConversionResult.ErrorUnableToOpenOfficeFile: // Handle source file being locked or invalid permissions break; case ConversionResult.ErrorUnableToAccessOfficeInterop: // Handle Office 2007 (Word | Excel | PowerPoint) not installed break; case ConversionResult.ErrorUnableToExportToXps: // Handle Microsoft Save As PDF or XPS Add-In missing for 2007 break; } |
Using Saaspose Document Converter (http://saaspose.com) you can convert any MS office document to XPS online for free.
Thank you so much, you saved my life
If I use this code through service(for word) I get this error: The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))
Also, the instance of word that is created has to be killed manually.
Hey Manuj,
I’m not sure why you’d be seeing that error. A quick Google search indicates that it might be due to Word attempting to show some dialog or alert but it’s set to not be visible by the code I posted. Try some of the results from this search.
Hi Mel,
I was looking for similar solution to view word document into silverlight 4 application.
Can we extend your solution in providing deep zoom or like page next /previous in XPS files to make complete word document viewer control and make it free for Silverlight/wfp community to use?
Thank you,
Vijay
Hey Vijay,
Like all the code on my blog this is completely free to use, modify, extend and release as you’d like!
Mel,
Word 2007 did the trick. I was able to run it.
Will continue to read the rest of your articles.
(I am java programmer just moved to WPF).
Thanks again!!!
Sarala
Mel,
Thanks for the quick response.
I am using Microsoft Word 2003. Interop Version 12.0.
Sarala
Sarala,
Word 2003 is most likely your problem. This solution should only work with Office 2007 or later since that’s when Microsoft introduced support for exporting to XPS.
I’m sorry I didn’t make that clearer in my original post. =\
Try it with Word 2007 or 2010 and see if you have better luck!
Thank you. I just downloaded the code. Have no compilation errors. But when I run it I get
“Attempted to read or write protected memory. This is often an indication that other memory is corrupt.” at wordDocument.ExportAsFixedFormat.
Not sure how to resolve this. Any help will be
appreciated
Hey Sarala,
This is likely due to an error with the particular Office Interop you’re using. What version of word are you testing this with? Have you installed the correct interop libraries for that version?
yes, thank you for this.