2013/05/13

C#.Net 讀取PowerPoint文字方塊內容

今天有跟同學稍微討論一下KINECT開發,他有提出一個問題是想取得PowerPoint的文字
既然我有興趣,就下海來寫啦XD

我沒記錯的話,必須先安裝好Office不然到時候呼叫COM元件會有問題
安裝好Office之後,Visual Studio2010會在加入參考的.Net出現Office家族的套件

今天範例是使用WPF實做



首先專案開啟完後,加入參考


把PowerPoint以及Office都加入參考


XAML
<Window x:Class="PowerPoint.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Open PowerPoint by C.Y. Fang" Height="350" Width="525" Loaded="Window_Loaded" Unloaded="Window_Unloaded">
    <Grid></Grid>
</Window>

表單載入時,就先透過OpenFileDialog開啟檔案,開啟完成後判斷是2003或2007


            OpenFileDialog dialog = new OpenFileDialog();

            //僅開啟2003 2007 ppt
            dialog.Filter = "2003 PPT (*.ppt)|*.ppt|2007 PPT (*.pptx)|*.pptx";

            //開啟檔案
            if (dialog.ShowDialog() == true)
            {
                //取得副檔名
                String tag = dialog.SafeFileName.Substring(dialog.SafeFileName.LastIndexOf('.'));

                //判斷是2003或2007
                if (tag.Equals(OFFICE_2003))    //2003
                {
                    pre = app.Presentations.Open(dialog.FileName, MsoTriState.msoCTrue, MsoTriState.msoFalse, MsoTriState.msoFalse);
                }
                else if (tag.Equals(OFFICE_2007))   //2007
                {
                    pre = app.Presentations.Open2007(dialog.FileName, MsoTriState.msoCTrue, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
                }


接著透過Slider去取得每一頁的資料 在透過Shape去判斷是否為文字方塊且包涵文字在裡頭,如果有就顯示出來 每秒輪撥一頁,可手動點擊

using System;
using System.Threading;
using System.Windows;
using Microsoft.Office.Core;
using Microsoft.Win32;
using POWER_POINT = Microsoft.Office.Interop.PowerPoint;

namespace PowerPoint
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        private POWER_POINT.Application app;
        private POWER_POINT.Presentation pre;
        private POWER_POINT.SlideShowSettings slider;
        private const String OFFICE_2003 = ".ppt";
        private const String OFFICE_2007 = ".pptx";

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            app = new POWER_POINT.Application();

            OpenFileDialog dialog = new OpenFileDialog();

            //僅開啟2003 2007 ppt
            dialog.Filter = "2003 PPT (*.ppt)|*.ppt|2007 PPT (*.pptx)|*.pptx";

            //開啟檔案
            if (dialog.ShowDialog() == true)
            {
                //取得副檔名
                String tag = dialog.SafeFileName.Substring(dialog.SafeFileName.LastIndexOf('.'));

                //判斷是2003或2007
                if (tag.Equals(OFFICE_2003))    //2003
                {
                    pre = app.Presentations.Open(dialog.FileName, MsoTriState.msoCTrue, MsoTriState.msoFalse, MsoTriState.msoFalse);
                }
                else if (tag.Equals(OFFICE_2007))   //2007
                {
                    pre = app.Presentations.Open2007(dialog.FileName, MsoTriState.msoCTrue, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
                }

                slider = pre.SlideShowSettings;

                //開始播放
                slider.Run();
                try
                {
                    //取得每篇頁數
                    for (int index = 0; index < pre.Slides.Count; index++)
                    {
                        //等待一秒輪撥一次
                        Thread.Sleep(1000);
                        NextSlide();

                        //取得頁數
                        foreach (POWER_POINT.Shape shape in pre.Slides[index + 1].Shapes)
                        {
                            //判斷有沒有文字方塊
                            if (shape.HasTextFrame == MsoTriState.msoTrue)
                            {
                                //判斷文字方塊內是否有文字
                                if (shape.TextFrame.HasText == MsoTriState.msoTrue)
                                {
                                    //http://msdn.microsoft.com/en-us/library/ff760948(v=office.14).aspx
                                    //http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.textrange_members(v=office.14).aspx
                                    POWER_POINT.TextRange range = shape.TextFrame.TextRange;

                                    //取得文字
                                    MessageBox.Show(range.Text);
                                }
                            }
                        }

                        //關閉程式
                        this.Close();
                    }
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            if (app != null)
            {
                app.Quit();
            }
        }

        #region 下一頁

        private void NextSlide()
        {
            if (app != null && pre != null)
            {
                pre.SlideShowWindow.View.Next();
            }
        }

        #endregion 下一頁

        #region 上一頁

        private void PreviousSlide()
        {
            if (app != null && pre != null)
            {
                pre.SlideShowWindow.View.Previous();
            }
        }

        #endregion 上一頁
    }
}

這次Demo的ppt用的是義守數學系的離散數學PPT








參考資料: http://www.cnblogs.com/arongbest/archive/2011/03/02/1969169.html http://mantascode.com/c-get-text-content-from-microsoft-powerpoint-file/ http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.textrange_members(v=office.14).aspx