WPF打开操作Office文档的解决办法

时间:2022-02-07 05:47:03

转载自: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文件,而且支持显示文件内的图形,表格等各类元素!

WPF打开操作Office文档的解决办法

本文完整代码下载