转载自:http://blog.csdn.net/soft2buy/article/details/6448448
http://code.msdn.microsoft.com/office/CSVSTOViewWordInWPF-db347436
最近在一个项目碰到一个问题,要用WPF打开并显示打印Office文档。包括Word, Excel, 和PowerPoint文档。找了很多资料,解决方案之一:调用第三方开发的Word, Excel, PowerPoint解析控件,三个不同的人开发的,要使用三个控件才能解决这个问题。而且有些控件对解析表格和图片还存在问题。
所以只好使用第二个解决方案,把Office文档先转换成XPS,然后用DocumentViewer来显示XPS。
所以解决方案的操作流程是:打开Office文档=》转换并在硬盘生成XPS=》加载显示XPS=》任务完成后删除XPS。
以下代码适用于目标计算机已安装Office2007或以上版本,对于Office 2003,需要下载 Office升级插件
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=3C9A983A-AC14-4125-8BA0-D36D67E0F4AD
那我们开始吧:
在一个工程文件添加如下引用:
Microsoft.Office.Interop.Excel(C:/Program Files/Microsoft Visual Studio 10.0/Visual Studio Tools for Office/PIA/Office12/Microsoft.Office.Interop.Excel.dll)
Microsoft.Office.Interop.PowerPoint(C:/Program Files/Microsoft Visual Studio 10.0/Visual Studio Tools for Office/PIA/Office12/Microsoft.Office.Interop.PowerPoint.dll)
Microsoft.Office.Interop.Word(C:/Program Files/Microsoft Visual Studio 10.0/Visual Studio Tools for Office/PIA/Office12/Microsoft.Office.Interop.Word.dll)
OFFICE(C:/Windows/assembly/GAC/office/12.0.0.0__71e9bce111e9429c/OFFICE.DLL)
ReachFramework
(C:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0/ReachFramework.dll
以上的引用可直接在引用窗口点击“浏览”,直接找到相应的DLL,并添加就可以了。
我们先完成最关键的步骤:Office文档转成XPS
首先创建一个转换类:
OfficeToXps.cs
代码如下:
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 Office_To_XPS { 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.IsNullOrEmpty(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.IsNullOrEmpty(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.IsNullOrEmpty(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 } }
有了这个类,我们可以轻而易举的把Word, Excel和 PPT文档转成XPS。
调用方法如下:
private void button1_Click(object sender, RoutedEventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.CheckFileExists = true; dlg.Filter = "PowerPoint Format (*.ppt,*.pptx)|*.ppt;*.pptx|" + "All files (*.*)|*.*"; if ((bool)dlg.ShowDialog(this)) { string filePath = dlg.FileName; string xpsFilePath = dlg.FileName + ".xps"; PleaseWait pw = new PleaseWait(); pw.Owner = this; pw.Show(); var convertResults = OfficeToXps.ConvertToXps(filePath, ref xpsFilePath); pw.Close(); switch (convertResults.Result) { case ConversionResult.OK: Xps_Document xps = new Xps_Document(xpsFilePath); xps.Owner = this; xps.Show(); break; case ConversionResult.InvalidFilePath: // 处理文件路径错误或文件不存在 break; case ConversionResult.UnexpectedError: break; case ConversionResult.ErrorUnableToInitializeOfficeApp: // Office2007 未安装会出现这个异常 break; case ConversionResult.ErrorUnableToOpenOfficeFile: // 文件被占用会出现这个异常 break; case ConversionResult.ErrorUnableToAccessOfficeInterop: // Office2007 未安装会出现这个异常 break; case ConversionResult.ErrorUnableToExportToXps: // 微软 OFFICE2007 Save As PDF 或 XPS 插件未安装异常 break; } } }
由于有些文档可能很大,为了保证在完全转换后才加载XPS,我们可以接收OfficeToXps.cs里ConversionResult属性,只有在接收到ConversionResult.OK属性的情况下,才能开始加载XPS文件。
为了让用户稍作等待,我们这里姑且用一个比较简陋的方法提示用户等待。
PleaseWait pw =new PleaseWait();
pw.Owner = this;
pw.Show();
我们打开一个无边框的窗体,上面写着“请等待”。大家也可以使用WPFToolKit里的BusyIndicator;
转换完成后,pw.Close();关闭窗体。
加载XPS的代码非常简单:
在窗体的XAML里定义一个DocumentViewer:
<Window x:Class="Office_To_XPS.Xps_Document" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="XpsDocument" Height="413" Width="605" WindowStartupLocation="CenterScreen"> <DocumentViewer x:Name="xpsDoc"/> </Window>
在C#里:
privatevoid LoadXPSFile(string _xpsfile) { using (XpsDocument xpsDoc =new XpsDocument(_xpsfile,FileAccess.Read)) { var fs = xpsDoc.GetFixedDocumentSequence(); this.xpsDoc.Document = fs; } }
大功告成!效果图如下图所示:
可以打开任何Word, Excel, PowerPoint文件,而且支持显示文件内的图形,表格等各类元素!
本文完整代码下载