日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Excel插件開發(fā)

 vbavsto 2021-04-29

1.本例開發(fā)了一個(gè)Excel 文檔管理的插件,基于VS2012 和Excel2010,先上效果圖

2.技術(shù)原理:使用Excel提供的自定義任務(wù)面板即CTP技術(shù)以及Ribbon菜單實(shí)現(xiàn)

1.先新增一個(gè)Ribbon 菜單,本人給的名字是UserRibbon,就是開始菜單的第一個(gè)文檔管理的按鈕,控制是否打開文檔管理的那個(gè)自定義任務(wù)面板

2.增加一個(gè)UserControl,里面加上TreeView控件,來顯示三種EXcel文檔(當(dāng)前打開文檔,經(jīng)常使用文檔,最近使用文檔)

3.加載任務(wù)面板代碼段

  1. <pre name="code" class="csharp">using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Xml.Linq;
  6. using Excel = Microsoft.Office.Interop.Excel;
  7. using Office = Microsoft.Office.Core;
  8. using Microsoft.Office.Tools.Excel;
  9. using Microsoft.Office.Core;
  10. using System.Diagnostics;
  11. using System.Runtime.InteropServices;
  12. namespace OfficeDocM
  13. {
  14. public partial class ThisAddIn
  15. {
  16. // 定義一個(gè)任務(wù)窗體
  17. internal Microsoft.Office.Tools.CustomTaskPane DocManageTaskPane;
  18. internal DocExplorer docExplorer;
  19. internal Excel.Application ExcelApp;
  20. private void ThisAddIn_Startup(object sender, System.EventArgs e)
  21. {
  22. //SingleInstanceCheck(); 有點(diǎn)問題先不控制
  23. Init();
  24. }
  25. private void Init()
  26. {
  27. //初始化
  28. ExcelApp = Globals.ThisAddIn.Application;
  29. //實(shí)例化文檔瀏覽器窗口
  30. docExplorer = new DocExplorer();
  31. //注冊(cè)Excel打開事件
  32. Globals.ThisAddIn.Application.WorkbookOpen += Application_WorkbookOpen;
  33. //加載自定義面板
  34. DocManageTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(docExplorer, "文檔瀏覽器");
  35. ShowDocManageTaskPane(MsoCTPDockPosition.msoCTPDockPositionLeft);
  36. }
  37. //處理Excel打開事件
  38. private void Application_WorkbookOpen(Excel.Workbook Wb)
  39. {
  40. docExplorer.SetFileList(Wb.Path, ExcelApp.ActiveWorkbook.Name);
  41. }
  42. private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
  43. {
  44. }
  45. public void ShowDocManageTaskPane(MsoCTPDockPosition postion = MsoCTPDockPosition.msoCTPDockPositionLeft)
  46. {
  47. // 使任務(wù)窗體可見
  48. DocManageTaskPane.Visible = true;
  49. DocManageTaskPane.DockPosition = postion;
  50. }
  51. public void HideDocManageTaskPane()
  52. {
  53. // 使任務(wù)窗體不可見
  54. DocManageTaskPane.Visible = false;
  55. }
  56. #region VSTO 生成的代碼
  57. /// <summary>
  58. /// 設(shè)計(jì)器支持所需的方法 - 不要
  59. /// 使用代碼編輯器修改此方法的內(nèi)容。
  60. /// </summary>
  61. private void InternalStartup()
  62. {
  63. this.Startup += new System.EventHandler(ThisAddIn_Startup);
  64. this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
  65. }
  66. #endregion
  67. }
  68. //非托管代碼部分(引用Win32API)
  69. public partial class ThisAddIn
  70. {
  71. [DllImport("User32.dll ")]
  72. private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
  73. //單實(shí)例檢查
  74. private void SingleInstanceCheck()
  75. {
  76. int Process_min_id;
  77. Process[] processes = Process.GetProcessesByName("EXCEL");
  78. Process_min_id = processes[0].Id;
  79. //殺死其他進(jìn)程
  80. if (processes.Length > 1)
  81. {
  82. for (int i = 1; i < processes.Length; i++)
  83. {
  84. if (Process_min_id < processes[i].Id)
  85. processes[i].Kill();
  86. else
  87. {
  88. Process.GetProcessById(Process_min_id).Kill();
  89. Process_min_id = processes[i].Id;
  90. }
  91. }
  92. }
  93. //顯示最開始的進(jìn)程
  94. ShowWindowAsync(Process.GetProcessById(Process_min_id).MainWindowHandle, 1);
  95. }
  96. }
  97. }
4 操作文檔管理代碼段
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using Excel=Microsoft.Office.Interop.Excel;
  10. using System.IO;
  11. using System.Xml;
  12. using System.Collections;
  13. using System.Reflection;
  14. using Microsoft.Win32;
  15. namespace OfficeDocM
  16. {
  17. public partial class DocExplorer : UserControl
  18. {
  19. Excel.Application ExcelApp;
  20. Excel.Workbooks ExcelWorkBooks;
  21. Hashtable ht_common = new Hashtable(); //保存常用的excel
  22. Hashtable ht_cuureet = new Hashtable();//保存當(dāng)時(shí)的excel
  23. TreeNode root = new TreeNode();//根節(jié)點(diǎn)
  24. TreeNode common_root = new TreeNode();//常用根節(jié)點(diǎn)
  25. TreeNode current_root = new TreeNode();//當(dāng)前根節(jié)點(diǎn)
  26. TreeNode recent_root = new TreeNode();//最近使用根節(jié)點(diǎn)
  27. public DocExplorer()
  28. {
  29. InitializeComponent();
  30. Init();
  31. }
  32. public void Init()
  33. {
  34. ExcelApp = Globals.ThisAddIn.Application;
  35. ExcelWorkBooks = ExcelApp.Workbooks;
  36. //樹根初始化
  37. TreeViewInit();
  38. //加載XML常用文件配置
  39. LoadCommonFiles();
  40. //加載最近使用文件
  41. LoadRecentFiles();
  42. }
  43. public void SetFileList(string filePath, string fileName)
  44. {
  45. string fileFullPath;
  46. fileFullPath = filePath + @"\" + fileName;
  47. if (File.Exists(fileFullPath))
  48. {
  49. TreeNode chldNode = new TreeNode();
  50. chldNode.Name = fileFullPath;
  51. chldNode.Text = fileName;
  52. current_root.Nodes.Add(chldNode);
  53. chldNode.ForeColor = Color.Red;
  54. if (!current_root.IsExpanded)
  55. current_root.ExpandAll();
  56. }
  57. }
  58. //單擊打開文件
  59. private void treeView_FileList_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
  60. {
  61. //創(chuàng)建Excel控件對(duì)象
  62. string Excelpath;
  63. Boolean docExists = false;
  64. if (e.Node.Level == 2 && e.Button==MouseButtons.Left)//左鍵單擊葉子節(jié)點(diǎn)打開文件
  65. {
  66. Excelpath = treeView_FileList.SelectedNode.Name;
  67. foreach (Excel._Workbook wb in ExcelWorkBooks)
  68. {
  69. if (Excelpath == wb.FullName)
  70. {
  71. wb.Activate();
  72. docExists = true;
  73. break;
  74. }
  75. }
  76. if (!docExists)
  77. {
  78. if (File.Exists(Excelpath))
  79. {
  80. //監(jiān)聽了excel 打開事件,當(dāng)前使用文檔統(tǒng)一在打開事件里面處理
  81. ExcelWorkBooks.Open(Excelpath);
  82. if (!current_root.IsExpanded)
  83. current_root.ExpandAll();
  84. }
  85. else
  86. MessageBox.Show("文件不存在!");
  87. }
  88. }
  89. }
  90. //雙擊關(guān)閉文件
  91. private void treeView_FileList_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
  92. {
  93. if (e.Node.Parent == current_root && e.Node.Level==2)//雙擊打開文件則關(guān)閉
  94. {
  95. foreach (Excel._Workbook wb in ExcelWorkBooks)
  96. {
  97. if (e.Node.Name == wb.FullName)
  98. {
  99. wb.Close();
  100. current_root.Nodes.Remove(e.Node);
  101. break;
  102. }
  103. }
  104. }
  105. }
  106. private void TreeViewInit()
  107. {
  108. root.Text = "文檔列表";
  109. current_root.Text = "當(dāng)前打開文檔";
  110. common_root.Text = "經(jīng)常使用文檔";
  111. recent_root.Text = "最近使用文檔";
  112. treeView_FileList.Nodes.Add(root);
  113. root.Nodes.Add(current_root);
  114. root.Nodes.Add(common_root);
  115. root.Nodes.Add(recent_root);
  116. if (!root.IsExpanded)
  117. {
  118. root.Expand();
  119. }
  120. }
  121. private void LoadCommonFiles()
  122. {
  123. string xmlPath;
  124. int firstIndex, lastIndex;
  125. RegistryKey Key;
  126. Key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Office\Excel\Addins\OfficeDocM");
  127. xmlPath = Key.GetValue("Manifest").ToString();
  128. Key.Close();
  129. firstIndex=xmlPath.IndexOf(":")+4;
  130. lastIndex=xmlPath.LastIndexOf("/");
  131. xmlPath=xmlPath.Substring(firstIndex, lastIndex - firstIndex);
  132. xmlPath = xmlPath + @"\CustExcels.xml";
  133. //加載XML
  134. XmlDocument xmlDoc = new XmlDocument();
  135. if (File.Exists(xmlPath))
  136. {
  137. xmlDoc.Load(xmlPath);
  138. //忽略注釋內(nèi)容
  139. XmlReaderSettings settings = new XmlReaderSettings();
  140. settings.IgnoreComments = true;
  141. //得到根節(jié)點(diǎn)
  142. XmlNode ExcelsNode = xmlDoc.SelectSingleNode("Excels");
  143. // 得到根節(jié)點(diǎn)的所有子節(jié)點(diǎn)
  144. XmlNodeList ExcelsNodeList = ExcelsNode.ChildNodes;
  145. foreach (XmlNode xnitem in ExcelsNodeList)
  146. {
  147. TreeNode chldNode = new TreeNode();
  148. string docPath, docName;
  149. // 將節(jié)點(diǎn)轉(zhuǎn)換為元素,便于得到節(jié)點(diǎn)的屬性值
  150. XmlElement excelList = (XmlElement)xnitem;
  151. // 得到excel節(jié)點(diǎn)的所有子節(jié)點(diǎn)
  152. XmlNodeList xnl0 = excelList.ChildNodes;
  153. docName = xnl0.Item(0).InnerText;
  154. docPath = xnl0.Item(1).InnerText;
  155. chldNode.Name = docPath + @"\" + docName;
  156. chldNode.Text = docName;
  157. chldNode.ForeColor = Color.Purple;
  158. common_root.Nodes.Add(chldNode);
  159. }
  160. if (!common_root.IsExpanded)
  161. common_root.ExpandAll();
  162. }
  163. else
  164. {
  165. Log my = new Log(@"D:\log.txt", FileMode.Create);
  166. my.Writeln(DateTime.Now.ToLocalTime().ToString()+"["+xmlPath+"]");
  167. }
  168. }
  169. private void LoadRecentFiles()
  170. {
  171. string fileFullPath,fileName;
  172. for (int i = 1; i <= ExcelApp.RecentFiles.Count; i++)
  173. {
  174. fileFullPath=ExcelApp.RecentFiles.get_Item(i).Name;
  175. if (File.Exists(fileFullPath))
  176. {
  177. fileName = System.IO.Path.GetFileName(fileFullPath);
  178. TreeNode chldNode = new TreeNode();
  179. chldNode.Name = fileFullPath;
  180. chldNode.Text = fileName;
  181. recent_root.Nodes.Add(chldNode);
  182. chldNode.ForeColor = Color.SteelBlue;
  183. if (!recent_root.IsExpanded)
  184. recent_root.ExpandAll();
  185. }
  186. }
  187. }
  188. /*因?yàn)閱螕暨x中的還是上次的節(jié)點(diǎn),那么在第一次加載上次的節(jié)點(diǎn)還是null的
  189. *所以使用單擊打開這個(gè)事件是必不可少的*/
  190. private void treeView_FileList_MouseDown(object sender, MouseEventArgs e)
  191. {
  192. if ((sender as TreeView) != null)
  193. {
  194. treeView_FileList.SelectedNode = treeView_FileList.GetNodeAt(e.X, e.Y);
  195. }
  196. }
  197. }
  198. }

5關(guān)鍵點(diǎn)說明

1.本例中使用到了一個(gè)XML文件作為配置文件,保存經(jīng)常使用的文檔信息,有一個(gè)問題就是,沒辦法確定這個(gè)文件的路徑,因?yàn)椴恢烙脩魰?huì)把這個(gè)插件安裝在哪里,各種方法試就是不行,突然靈機(jī)一動(dòng),Excel 怎么加載插件的,原來在注冊(cè)表,果然如此 就有了下面一段代碼(路徑里包含一些其他東西 就特別處理了一下)

  1. string xmlPath;
  2. int firstIndex, lastIndex;
  3. RegistryKey Key;
  4. Key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Office\Excel\Addins\OfficeDocM");
  5. xmlPath = Key.GetValue("Manifest").ToString();
  6. Key.Close();
  7. firstIndex=xmlPath.IndexOf(":")+4;
  8. lastIndex=xmlPath.LastIndexOf("/");
  9. xmlPath=xmlPath.Substring(firstIndex, lastIndex - firstIndex);
  10. xmlPath = xmlPath + @"\CustExcels.xml";
2.Ribbon  菜單位置的確定

                                                圖1                                                                                             圖2

   
2.1如果自己的菜單想獨(dú)立(與office本生的菜單如開始,插入等 平級(jí) Ribbon的ControlIDType 就選擇Custom,若想其作為一個(gè)字菜單就選Office,并通過OfficeId指定其屬于哪個(gè)菜單,如 圖1 )

2.2 子菜單位置確定,如 圖2 關(guān)鍵屬性 Position 

2.3 每個(gè)Office 菜單Id 見  office 菜單名稱


                                    

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多