DSOFramerControl簡單使用


  以前大學做項目(Web的畢業論系統)就看見過在網頁中嵌入Office的word,那時候用了哪個控件當時沒記下來,我倒是忘了,最近發現在WinForm要嵌入Office的話,可以使用DSOFramerControl。

 

環境

  使用之前要注冊一下COM組件才行,使用 regsvr32注冊 dsoframer.ocx。要是用這個的話,系統里面肯定要有裝Office,要是很好使用的話,還得有Office開發組件,獲得這組件的途徑可以是在安裝Office時把PIA也安裝上。在這里可以找到添加上工具箱

當然這篇文章中只涉及到Word的使用,這個控件其實能給Office的其余成員——Excel,Visio和PowerPoint使用。

 

外觀

控件運行起來就好比把一整個Word的窗口嵌在了當前開發的窗體中。

控件也大致包含了一個正常WinForm的基本元素,標題欄,工具欄,菜單欄。不過我用的是Office2013,它的標題欄和工具欄外觀比較特殊,采用選項卡形式,導致控件的菜單欄只有一個File按鈕。下面是網上看的到別的版本的Office的效果,菜單欄是齊的。

若要對標題欄,工具欄,菜單欄這些元素的顯示狀態進行更改,可設置以下幾個屬性

  • Titlebar
  • Menubar
  • Toolbar

這三個屬性都是布爾類型,光看名字就知道是設那個欄了。

 

基本文件操作

對一個Office的文件一般操作包括打開,關閉,保存。而打開可分為讀寫打開還有只讀打開;保存又可分成保存和另存為。

打開可以調用Open方法,聲明如下

        public virtual void Open(object document);
        public virtual void Open(object document, object readOnly, object progId, object webUsername, object webPassword);

Document參數是一個object類型,一般可以傳一個文件的全名過去

this.officeWord.Open(@"C:\Users\居士\Desktop\temp\博文\系統特殊路徑一覽.docx");

如果要只讀打開的話,可以使用重載的方法,第二個參數傳個False進去,打開的文檔雖然可以編輯,但是無法保存的。這個涉及到保存那個操作了,延后說。

關閉文檔則調用

public virtual void Close();

還有一種關閉則是涉及到Microsoft.Office.Interop.Word.DocumentClass

這個對象的,在過往使用中,曾經在關閉的時候沒處理好,導致word文檔一直處於被鎖狀態,每次打開只能以只讀方式打開。於是我會在窗體或者控件的Dispose中調用這么寫道

                Microsoft.Office.Interop.Word.Document doc = this.officeWord.ActiveDocument as Microsoft.Office.Interop.Word.Document;
                object missObj=null;
                doc.Close(ref missObj,ref missObj,ref missObj);

或者能把上面這段代碼封裝一下,然后在Form_Closing或者Form_Closed調用。

保存的方法聲明如下

        public virtual void Save();
        public virtual void Save(object saveAsDocument, object overwriteExisting, object webUsername, object webPassword);

一般保存的話可以直接調用Save()方法,但是如果是在控件的菜單欄里新建的文檔,該文檔還不是一個物理文件時,調用Save()方法則會引發異常。

利用DocumentClass保存。DocumentClass實現了Document接口,Documenet有以下幾個方法

1 void Save();
2 void SaveAs(ref object FileName = Type.Missing, ref object FileFormat = Type.Missing, ref object LockComments = Type.Missing, ref object Password = Type.Missing, ref object AddToRecentFiles = Type.Missing, ref object WritePassword = Type.Missing, ref object ReadOnlyRecommended = Type.Missing, ref object EmbedTrueTypeFonts = Type.Missing, ref object SaveNativePictureFormat = Type.Missing, ref object SaveFormsData = Type.Missing, ref object SaveAsAOCELetter = Type.Missing, ref object Encoding = Type.Missing, ref object InsertLineBreaks = Type.Missing, ref object AllowSubstitutions = Type.Missing, ref object LineEnding = Type.Missing, ref object AddBiDiMarks = Type.Missing);
3 
4 void SaveAs2(ref object FileName = Type.Missing, ref object FileFormat = Type.Missing, ref object LockComments = Type.Missing, ref object Password = Type.Missing, ref object AddToRecentFiles = Type.Missing, ref object WritePassword = Type.Missing, ref object ReadOnlyRecommended = Type.Missing, ref object EmbedTrueTypeFonts = Type.Missing, ref object SaveNativePictureFormat = Type.Missing, ref object SaveFormsData = Type.Missing, ref object SaveAsAOCELetter = Type.Missing, ref object Encoding = Type.Missing, ref object InsertLineBreaks = Type.Missing, ref object AllowSubstitutions = Type.Missing, ref object LineEnding = Type.Missing, ref object AddBiDiMarks = Type.Missing, ref object CompatibilityMode = Type.Missing);
5 
6 void SaveAs2000(ref object FileName = Type.Missing, ref object FileFormat = Type.Missing, ref object LockComments = Type.Missing, ref object Password = Type.Missing, ref object AddToRecentFiles = Type.Missing, ref object WritePassword = Type.Missing, ref object ReadOnlyRecommended = Type.Missing, ref object EmbedTrueTypeFonts = Type.Missing, ref object SaveNativePictureFormat = Type.Missing, ref object SaveFormsData = Type.Missing, ref object SaveAsAOCELetter = Type.Missing);

Save()就用在直接保存的,如果文檔不存在,則會彈出“另存為”的文件保存對話框。SaveAs是用於另存為的。至於SaveAs2和SaveAs2000則是對應着docx和doc兩種不同格式的文件。

  上面提及到的文檔只讀問題。如果以只讀方式打開的話,調用AxFramerControl的Save方法是會拋異常的。如果用重載的話,第二個參數overwriteExisting並且第一個參數文件名是原本打開的文件的話,是可以保存成功的。如果利用Document接口,調用Save()則會彈出另存為的則會彈出一個“另存為”的文件保存對話框。如果調用的是SaveAs,文件名是原本打開的文件的話,也是可以覆蓋保存的。

  這里提到的利用AxFramerControl的ActiveDocument屬性,它是一個Object類型的,它可以轉成DocumentClass類型,也可以轉成DocumentClass2類型。能用哪種類型還取決於用戶的系統上裝了哪個版本的Office,如果裝了Office 2007或以后版本的則可以使用DocumentClass和DocumentClass2;如果裝了Office 2007以前的版本的話,那只能用DocumentClass了。

 

  下面內容則涉及到對Word文檔內容的編輯,這里覺得有部分概念要先提一下。

  • 關於換行:Word文檔的換行符其實是“\r”,這有別於平常的程序開發里面用到的“\n”或者“\r\n”。它識別不了“\n”這個字符,如果在文字編輯時用了“\n”則會顯示別的字符上去。
  • 在Word里面是以Word(單詞或中文的詞)作為一個文字的基本單元,平時在編輯文檔時看到的紅色波浪下划線就是Word里面識別到這個word有錯誤才打上去的,一個或者多個的word可以組成Range,這個Range會在文字替換成圖片的地方用到。

  不過下面部分的內容都是Microsoft.Office.Interop.Word.Document接口的使用

 

替換文字

替換文字的方法可定義如下,其中oMissing可以是一個object類型的字段

        public void Replace(Document doc,string oldString, string newString)
        {
            doc.Content.Find.Text = oldString;
            object FindText, ReplaceWith, ReplaceAll;

            FindText = oldString;
            ReplaceWith = newString;
            ReplaceAll = word.WdReplace.wdReplaceAll;
            doc.Content.Find.Execute(ref FindText,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing,
                                      ref ReplaceWith,
                                      ref ReplaceAll,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing,
                                      ref oMissing);

        }

 

查找內容

查找內容的方法就用到Range這個類了。方法是我自己寫的,比較菜,而且只適用於查找第一個匹配的內容,往后匹配的都被忽略掉了。其實改改還是可以實現查詢所有匹配內容的。

        public Range FindRange(Document doc, string text)
        {
            Range range;
            object start,end;
            for (int i = 0; true; i++)
            { 
                start=i;end=i+text.Length;
                try{
                    range = doc.Range(ref start, ref end);
                    if (range.Text == text) return range;
                }
                catch (Exception ex) { break; }
            }

            return null;
        }

 

插入圖片

插入圖片要也要用到Range,其實上面的查找方法算是為調用這個方法而定義的。至於調整圖片的樣式,目前還沒有去考究

        private void AddImage(Document doc, string imageFile,Range range)
        {
            string fileName = imageFile;  //要插入的圖片
            Object oLinkToFile = false;  //缺省
            Object oSaveWithDocument = true;// 缺省
            doc.InlineShapes.AddPicture(fileName, ref  oLinkToFile, ref  oSaveWithDocument, ref  oMissed);
        }

此外在網上也找了一份DSOFramerControl的API文檔,附帶一下

 dso_api.rar

以上有什么說錯的說漏的歡迎大家批評指出,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM