2019年8月27日 星期二

[研究][C#]取得 PowerPoint (.pptx) 所有文字

[研究][C#]取得 PowerPoint (.pptx) 所有文字

2019-08-27

測試環境
Windows 10
PowerPoint 2016
Visual Studio 2019 Enterprise
NET Framework 4.8
因為使用 DocumentFormat.OpenXml 2.9.1,編譯時,方案/專案設定至少使用 .NET 4.6

執行環境
.NET Framework 4.6 或更高
不需要有 PowerPoint
不支援 .ppt,支援 .pptx  (因為 ppt 不是 OpenXML 格式文件)

參考
https://docs.microsoft.com/en-us/office/open-xml/how-to-get-all-the-text-in-a-slide-in-a-presentation

放幾個控制項:Button1 和 richTextBox1, openFileDialog, saveFileDialog



using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        private void Button1_Click(object sender, EventArgs e)
        {
            // Visual Studio 2019
            // WinForm 程式
            // NuGet 安裝 DocumentFormat.OpenXml 2.9.1
            // https://docs.microsoft.com/en-us/office/open-xml/how-to-get-all-the-text-in-a-slide-in-a-presentation
            var fileContent = string.Empty;
            var filePath = string.Empty;
         

            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.InitialDirectory = "c:\\";
                openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
                openFileDialog.FilterIndex = 2;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    //Get the path of specified file
                    filePath = openFileDialog.FileName;
                    //Read the contents of the file into a stream
                    //var fileStream = openFileDialog.OpenFile();

                    //using (StreamReader reader = new StreamReader(fileStream))
                    //{
                    //    fileContent = reader.ReadToEnd();
                    //}
                }
            }

            //string[] x = GetAllTextInPPTX("D:\\Test1.pptx");
            string[] x = GetAllTextInPPTX(filePath);
            string dir = Path.GetDirectoryName(filePath);
            for (int i = 0; i < x.Length; i++)
            {
                richTextBox1.Text = richTextBox1.Text + x[i] + "\n";
            }
            Stream myStream;
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            saveFileDialog1.FilterIndex = 2;
            saveFileDialog1.RestoreDirectory = true;
         
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                //if ((myStream = saveFileDialog1.OpenFile()) != null)
                //{
                //    // Code to write the stream goes here.
                //    myStream.Close();
                //}

                filePath = saveFileDialog1.FileName;
                richTextBox1.SaveFile(filePath, RichTextBoxStreamType.PlainText);
            }
        }

        public static string[] GetAllTextInPPTX(string presentationFile)
        {
            // Open the presentation as read-only.
            using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
            {
                // Verify that the presentation document exists.
                if (presentationDocument == null)
                {
                    throw new ArgumentNullException("presentationDocument");
                }

                // Get the presentation part of the presentation document.
                PresentationPart presentationPart = presentationDocument.PresentationPart;

                // Verify that the presentation part and presentation exist.
                if (presentationPart != null && presentationPart.Presentation != null)
                {
                    // Get the Presentation object from the presentation part.
                    Presentation presentation = presentationPart.Presentation;

                    // Verify that the slide ID list exists.
                    if (presentation.SlideIdList != null)
                    {
                        // Get the collection of slide IDs from the slide ID list.
                        DocumentFormat.OpenXml.OpenXmlElementList slideIds =
                            presentation.SlideIdList.ChildElements;

                        // Create a new linked list of strings.
                        LinkedList<string> texts = new LinkedList<string>();

                        // If the slide ID is in range...
                        for (int i=0; i < slideIds.Count; i++)
                        {
                            int slideIndex = i;
                            // Get the relationship ID of the slide.
                            string slidePartRelationshipId = (slideIds[slideIndex] as SlideId).RelationshipId;

                            // Get the specified slide part from the relationship ID.
                            SlidePart slidePart =
                                (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);

                            // Pass the slide part to the next method, and
                            // then return the array of strings that method
                            // returns to the previous method.

                            // Verify that the slide part exists.
                            if (slidePart == null)
                            {
                                throw new ArgumentNullException("slidePart");
                            }

                            // Create a new linked list of strings.
                            //LinkedList<string> texts = new LinkedList<string>();

                            // If the slide exists...
                            if (slidePart.Slide != null)
                            {
                                // Iterate through all the paragraphs in the slide.
                                foreach (DocumentFormat.OpenXml.Drawing.Paragraph paragraph in
                                    slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
                                {
                                    // Create a new string builder.                 
                                    StringBuilder paragraphText = new StringBuilder();

                                    // Iterate through the lines of the paragraph.
                                    foreach (DocumentFormat.OpenXml.Drawing.Text text in
                                        paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
                                    {
                                        // Append each line to the previous lines.
                                        paragraphText.Append(text.Text);
                                    }

                                    if (paragraphText.Length > 0)
                                    {
                                        // Add each paragraph to the linked list.
                                        texts.AddLast(paragraphText.ToString());
                                    }
                                }
                            }
                        } // for

                        if (texts.Count > 0)
                        {
                            // Return an array of strings.
                            return texts.ToArray();
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
            }
            return null;
        }
    }
}




(完)

沒有留言:

張貼留言