C#如何定製Excel介面並實現與資料庫互動
Excel是微軟辦公套裝軟體的一個重要的組成部分,它可以進行各種資料的處理、統計分析和輔助決策操作,廣泛地應用於管理、統計財經、金融等眾多領域。(另外,Excel還是倫敦一所會展中心的名稱)。.NET可以建立Excel Add-In對Excel進行功能擴充套件,這些擴充套件的功能包括自定義使用者函式,自定義UI,與資料庫進行資料互動等。
一 主要的Excel開發方式
1 VBA
VBA是一種Visual Basic的巨集語言,它是最早的Office提供定製化的一種解決方案,VBA是VB的一個子集,和Visual Basic不同,VBA是一種宿主型語言,無論是專業的開發人員,還是剛入門的非開發人員,都可以利用VBA完成簡單或複雜的需求。
2 Excel 外掛
Excel Addin,就像Visual Studio外接外掛一樣,也可以使用一些技術為Office開發一些外掛。對VBA的一些問題,一些專業的開發人員,可以使用 VisualBasic或者VisualC++等工具來引用Office的一些dll,來針對Office進行開發。開發的時候將dll註冊為com組 件,並在登錄檔裡面進行註冊,這樣就可以在Excel裡直接呼叫這些外掛。
3 VSTO(Office 的 Visual Studio 工具)
VSTO主要是對Office的一些dll進行了.NET封裝,使得我們可以使用.NET上的語言來方便的對Office的一些方法進行呼叫。所 以,Office開發跨入了一個新的時代,開發人員可以使用更加高階的語言和熟悉的技術來更容易的進行Office開發。對於企業及的應用和開發,VSTO或許是首要選擇,他極大地擴充套件了Office應用程式的能力,使用.NET平臺支援的程式語言,能夠直接訪問.NET上面眾多的類庫。具有較好的安全機制。簡化了Office外掛的開發和部署。
4 XLL
XLL是Excel的一種外接應用程式,他使用C和C++開發,程式通過呼叫Excel暴漏的C介面來實現擴充套件功能。這種方式開發的應用程式效率高,但是難度大,對開發者自身的要求較高。開源專案Excel-DNA就是使用XLL技術開發的,能夠幫助.NET 開發人員來極大地簡化RTD函式,同步、非同步UDF函式的編寫和開發。
5 OpenXML
如果使用者沒有安裝Excel應用程式,或者在伺服器端需要動態生成Excel檔案的時候。我們可能需要直接讀取或者生成Excel檔案,這種情況下,如果要對Excel檔案進行各種定製化開發的話,建議使用OpenXML。NPOI開源專案可以直接讀寫Excel檔案,而且相容多個版本。
二 使用Excel Add-In構建擴充套件
開發環境: 作業系統為Windows Server 2008R2 x64;Excel為Excel 2010 x64;開發工具為Visual Studio 2012旗艦版x64;資料庫為SQL Server 2008R2 x64.
1 程式結構
用Visual Studio 2012新建一個ExcelAddInDemo的Excel Add-In專案,並新增若干檔案,程式結構如下圖:
其中,RibbonAddIn可以定製2010的UI面板,SqlHelper.cs是一個簡單的資料庫訪問幫助類,UClog.cs,UCPaneLeft.cs,UCTaskGrid.cs,UCTaskPane.cs都為新增的自定義控制元件,並通過程式新增到EXCEL介面中.執行起來的介面如下:
程式可以通過在Excel介面中輸入ID,First,Last,Email的值(對應標籤的後一個單元格),單擊使用者列表面板上的儲存按鈕,將資料儲存到資料庫中.
2 RibbonAddIn設計
我們通過RibbonAddIn.cs給Excel的Ribbon添加了一個名為CUMT的外掛.RibbonAddIn面板可以通過工具條控制元件方便的拖放到設計介面上.RibbonAddIn.cs的屬性設定如下圖所示:
後臺程式碼如下:
1 使用 系統;
2 使用 System.Collections.Generic;
3 使用 System.Linq;
4 使用 System.Text;
5 使用 Microsoft.Office.Tools.Ribbon;
6
7 名稱空間 ExcelAddInDemo
8 {
9 公共 部分 類 RibbonAddIn
10 {
11
12 private void RibbonAddIn_Load( 物件 傳送者,RibbonUIEventArgs e)
13 {
14
15 }
16
17 private void btnAbout_Click( 物件 傳送者,RibbonControlEventArgs e)
18 {
19 System.Windows.Forms.MessageBox.Show( “ JackWangCUMT! ” );
20 }
21
22 private void btnShow_Click( 物件 傳送者,RibbonControlEventArgs e)
23 {
24 if (Globals.ThisAddIn._MyCustomTaskPane != null )
25 {
26 Globals.ThisAddIn._MyCustomTaskPane.Visible = true ;
27 }
28 }
29
30 private void btnHide_Click( 物件 傳送者,RibbonControlEventArgs e)
31 {
32 if (Globals.ThisAddIn._MyCustomTaskPane != null )
33 {
34 Globals.ThisAddIn._MyCustomTaskPane.Visible = false ;
35 }
36 }
37 }
38 }
3ThisAddIn邏輯編寫
1 使用 系統;
2 使用 System.Collections.Generic;
3 使用 System.Linq;
4 使用 System.Text;
5 使用 System.Xml.Linq;
6 使用 Excel = Microsoft.Office.Interop.Excel;
7 名稱空間 ExcelAddInDemo
8 {
9 使用 Microsoft.Office.Tools;
10 公共 部分 類 ThisAddIn
11 {
12 公共 CustomTaskPane _MyCustomTaskPane = null ;
13
14 private void ThisAddIn_Startup( 物件 傳送者,System.EventArgs e)
15 {
16 UCTaskPane taskPane = new UCTaskPane();
17 _MyCustomTaskPane = this .CustomTaskPanes.Add(taskPane, " 我的任務面板 " );
18 _MyCustomTaskPane.Width = 30 ; // height 有問題,此處width ==height
19 _MyCustomTaskPane.Visible = true ;
20 _MyCustomTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionTop;
21
22 UCPaneLeft panLeft = new UCPaneLeft();
23 _MyCustomTaskPane = this .CustomTaskPanes.Add(panLeft, " 組織 " );
24 _MyCustomTaskPane.Width = 200 ;
25 _MyCustomTaskPane.Visible = true ;
26 _MyCustomTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionLeft;
27
28 UCTaskGrid panRight = new UCTaskGrid();
29 _MyCustomTaskPane = this .CustomTaskPanes.Add(panRight, " 使用者列表 " );
30 _MyCustomTaskPane.Width = 200 ;
31 _MyCustomTaskPane.Visible = true ;
32 _MyCustomTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight;
33
34 UCLog panLog = new UCLog();
35 _MyCustomTaskPane = this .CustomTaskPanes.Add(panLog, " 日誌列表 " );
36 _MyCustomTaskPane.Width = 60 ;
37 _MyCustomTaskPane.Visible = true ;
38 _MyCustomTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionBottom;
39
40 // 掛鉤工作簿開啟事件
41 // 這是因為執行此方法時,Office 並不總是準備好文件
42 this .Application.WorkbookActivate += Application_WorkbookActivate;
43 // 測試
44 // this.Application.SheetSelectionChange += Application_SheetSelectionChange;
45 }
46
47 void Application_SheetSelectionChange( object Sh, Excel.Range Target)
48 {
49 如果 ( 這個 .Application != null )
50 {
51 this .Application.Caption = this .Application.ActiveCell.Address.ToString(); // 1 澳元
52 // + this.Application.ActiveCell.AddressLocal.ToString(); // 1 澳元
53 // this.Application.ActiveCell.Formula = "=sum(1+2)";
54
55 }
56 }
57
58 無效 Application_WorkbookActivate(Excel.Workbook Wb)
59 {
60 // using Microsoft.Office.Tools.Excel 和 using Microsoft.Office.Interop.Excel 等,容易重新調整
61 // 字串路徑 = this.Application.ActiveWorkbook.FullName;
62 Excel._Worksheet ws = (Excel._Worksheet) this .Application.ActiveWorkbook.ActiveSheet;
63 ws.Cells[ 2 , 2 ] = " ID2 " ;
64 // 如何設定只讀等有待研究
65 int r= 2 ,c= 2 ;
66 // ((Excel.Range)ws.Cells[r, c]).NumberFormat = format;
67 ((Excel.Range)ws.Cells[r, c]).Value2 = " ID " ;
68 ((Excel.Range)ws.Cells[r, c]).Interior.Color = System.Drawing。 ColorTranslator.ToOle(System.Drawing.Color.Red);
69 // ((Excel.Range)ws.Cells[r, c]).Style.Name = "Normal";
70 ((Excel.Range)ws.Cells[r, c]).Style.Font.Bold = true ;
71
72 #region 格式
73 ((Microsoft.Office.Interop.Excel.Range)ws.get_Range( " A2 " , " E10 " )).Font.Bold = true ;
74 ((Microsoft.Office.Interop.Excel.Range)ws.get_Range( " A2 " , " E10 " )).Font.Italic = true ;
75 ((Microsoft.Office.Interop.Excel.Range)ws.get_Range( " A2 " , " E10 " )).Font.Color = System.Drawing.Color.FromArgb( 96 , 32 , 0 ).ToArgb();