C# 開發excel addin插件的小積累

好吧,進園子這麼長時間了,第一次寫博文,歡迎拍磚!php

關於excel的一些基本操做:html

一、引用正則表達式

開發excel插件,這兩個引用是必不可少的。app

using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Tools.Ribbon;

二、 工做簿、工做表、單元格的操做ide

ApplicationClass application = new ApplicationClass(); //建立一個excel進程
Workbook wbook = Globals.ThisAddIn.Application.ActiveWorkbook; //當前活動workbook
Worksheet worksheet = (Worksheet)wbook.ActiveSheet; //當前活動sheet
Range range = (Range)worksheet.Application.Selection;//當前選中的cells

根據條件選擇指定的sheet:函數

Worksheet worksheet = wbook.Worksheets["sheet1"];//獲取名爲sheet1的工做表
Worksheet worksheet = wbook.Worksheets[1];//獲取第一個工做表

其餘的操做:工具

workSheet.Range[workSheet.Cells[range.Row,1],workSheet.Cells[workSheet.UsedRange.Rows.Count,workSheet.UsedRange.Columns.Count]].Clear();//清除當前選定行如下的全部數據
workSheet.UsedRange.Rows.Count//已使用的行數
workSheet.UsedRange.Columns.Count//已使用的列數
worksheet.Range["A1"].Font.ColorIndex = 3;//將「A1」單元格字體設爲紅色
worksheet.Range["A1","B2"].Interior.ColorIndex = 3; //將「A1」到「B2」範圍背景設爲紅色
int num = wss1.Range[wss1.Cells[1, Y1]].Find("").Row; //第一次出現空單元格的行數
worksheet.Cells["A1"].Rows.Hidden=true;//隱藏行
worksheet.Cells["A1"].Columns.Hidden=true;//隱藏列
View Code

range與cells的區別不大,最重要的事range的範圍比cells大;學習

固然,用C#遍歷全部單元格時若遇到空單元格,有可能會彈出「沒法對null執行運行時綁定」,此時對單元格判斷是否爲空並用正則表達式匹配數字,而後比較大小的方法(將全部小於6的數字字體設爲紅色):開發工具

1 string str = Convert.ToString(worksheet.Cells[i, j].value);
2 string regex = @"^[1-9]\d*|0$";
3 if (str != null && Regex.IsMatch(str, regex))
4 {
5      if (Convert.ToDouble(str) < 6)
6      {
7         worksheet.Cells[i, j].Font.ColorIndex = 3;
8      }
9 }
View Code

三、 圖表生成字體

(1)如下是生成柱狀圖的方法(綁定數據的兩種方法,一種是連續綁定數據,數據是連續的;另外一種是部分綁定,數據是不連續的):

 1 wbook.Charts.Add(Type.Missing); //添加一個頁面
 2 wbook.ActiveChart.ChartType = XlChartType.xlColumnClustered; //設置要顯示的圖表樣式(簇狀條形圖)      
 3 Range rang = worksheet.get_Range(strx + "," + stry);
 4 wbook.ActiveChart.SetSourceData(rang, XlRowCol.xlColumns);//數據不連續
 5 //wbook.ActiveChart.SetSourceData(ws.Range["A1",ws.Cells[ws.UsedRange.Rows.Count,ws.UsedRange.Columns.Count]], XlRowCol.xlRows);//綁定數據,數據是連續的
 6 //wbook.ActiveChart.SetSourceData(ws.Range["A1","A40"], XlRowCol.xlColumns);//綁定數據,柱狀圖中圖柱所表明的數據
 7 //沒有這個標題就出不來
 8 wbook.ActiveChart.HasTitle = true;
 9 //設置繪圖區的數據標誌(就是線形頂上出現值)顯示出值來
10 wbook.ActiveChart.ApplyDataLabels(XlDataLabelsType.xlDataLabelsShowValue, false, false, false, false, false,true, false, false, false);
11 //後面一坨也是有用的,例如要顯示餅圖的百分比,就必須將倒數第三個false改成true
12 //設置Legend圖例的位置和格式
13 wbook.ActiveChart.HasLegend = true;
14 wbook.ActiveChart.PlotArea.Width = 550; //設置繪圖區寬度
15 wbook.ActiveChart.PlotArea.Top = 30;
16 wbook.ActiveChart.PlotArea.Height = 400; //設置繪圖區高度
17 wbook.ActiveChart.PlotArea.Left = 20;
18 //表示圖示畫在SHEET1的,改爲本身的SHEET名就好
19 wbook.ActiveChart.Location(XlChartLocation.xlLocationAsObject, aimWorksheet.Name);
20 //圖形距離左上角的距離
21 //wbook.ActiveSheet.ChartObjects.count //當前表中chart的數量
22 wbook.ActiveChart.ChartArea.Top = (wbook.ActiveSheet.ChartObjects.count - 1) * 200 + wbook.ActiveSheet.ChartObjects.count * 20;
23 wbook.ActiveChart.ChartArea.Left = 20;
24 wbook.ActiveChart.ChartArea.Height = 200;
25 wbook.ActiveChart.ChartArea.Width = 600;
26 //x軸樣式
27 Axis xAxis = (Axis)wbook.ActiveChart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary);
28 //y軸樣式
29 Axis yAxis = (Axis)wbook.ActiveChart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
30 //  xAxis.CategoryNames = ws.Range["B2", ws.Cells[ws.UsedRange.Rows.Count, 2]];//x軸標註信息綁定
31 xAxis.HasTitle = false;
32 xAxis.TickLabels.Font.Name = "宋體";
33 xAxis.TickLabels.Font.Size = 8;
34 yAxis.TickLabels.NumberFormat = "##元"; //能夠經過格式指定y軸的顯示方式
35 yAxis.TickLabels.Orientation = Microsoft.Office.Interop.Excel.XlTickLabelOrientation.xlTickLabelOrientationHorizontal;
36 //Y軸顯示的方向,是水平仍是垂直等
37 yAxis.TickLabels.Font.Size = 8;
38 yAxis.TickLabels.Font.Name = "宋體";
39  //設置標題和座標軸
40 wbook.ActiveChart.HasTitle = true;
41 wbook.ActiveChart.ChartTitle.Text = str4+"柱狀圖"; //將默認標題改成指定標題
42 wbook.ActiveChart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary).HasTitle = true;
43 wbook.ActiveChart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary).AxisTitle.Characters.Text = str3;//在x軸上顯示橫座標
44 wbook.ActiveChart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary).HasTitle = true;
45 wbook.ActiveChart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary).AxisTitle.Characters.Text = str4;//在y軸上顯示縱座標
View Code

固然生成圖表並非結束,咱們還能夠對其進行修改(下面是對當前選中的圖表數據進行修改,try部分是爲了若是是餅形圖修改數據不會報錯):

 1 Range rang = swsheet.get_Range(str1 + "," + str2);
 2 wbook.ActiveChart.SetSourceData(rang, XlRowCol.xlColumns);
 3 //設置標題和座標軸
 4 wbook.ActiveChart.HasTitle = true;
 5 wbook.ActiveChart.ChartTitle.Text = comboBox4.SelectedItem + ""; //將默認標題改成指定標題
 6 try
 7 {
 8 wbook.ActiveChart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary).HasTitle = true;
 9 wbook.ActiveChart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary).AxisTitle.Characters.Text =
10 comboBox5.SelectedItem.ToString(); //在x軸上顯示橫座標
11 wbook.ActiveChart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary).HasTitle = true;
12 wbook.ActiveChart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary).AxisTitle.Characters.Text =
13 comboBox1.SelectedItem.ToString(); //在y軸上顯示縱座標
14 }
15 catch (Exception exception)
16 {
17 }
View Code

還能夠對圖表的數據源進行篩選,篩選不是將無關數據刪除,只是將其隱藏起來,隱藏數據的值和位置都是不變的:

swsheet.Range["A1",swsheet.Cells[swsheet.UsedRange.Rows.Count, swsheet.UsedRange.Columns.Count]].AutoFilter(x, 「>1」, XlAutoFilterOperator.xlAnd, Type.Missing, true); //篩選選定區域第x列全部大於1的數據
wss1.Range[wss1.Cells[1, i], wss1.Cells[wss1.UsedRange.Rows.Count, i]].AdvancedFilter(XlFilterAction.xlFilterCopy, Type.Missing, wss1.Range["AZ1"], true);//將不重複數據寫到Z列

(2)數據透視表

即水晶報表,將數據進行統計(下面進行多數據綁定中的兩種方法:一個是pivotTable.AddFields能夠綁定除數據求和項外的全部數據;若想求和項也綁定多數據,能夠定義多個PivotField pivotField,由於一個sheet中只能有一個數據透視表):

 1 private void GeneratetPivot1(Worksheet worksheet, Workbook wbook, Worksheet wss1)
 2 {
 3 PivotCaches pivotCaches = wbook.PivotCaches();
 4 PivotCache pivotCache = pivotCaches.Add(XlPivotTableSourceType.xlDatabase, worksheet.UsedRange);//可選擇數據綁定
 5 Range range = wss1.Range["A1", wss1.Cells[wss1.UsedRange.Rows.Count, wss1.UsedRange.Columns.Count]];//透視表起始位置
 6 //建立數據透視表
 7 PivotTable pivotTable = pivotCache.CreatePivotTable(range, wss1.Name, true,
 8 XlPivotTableVersionList.xlPivotTableVersionCurrent);
 9 pivotTable.AddFields("合同名稱", Type.Missing, Type.Missing, true); //向數據透視表或數據透視圖中添加行字段、列字段和頁字段。
10 pivotTable.AddFields(Type.Missing, Type.Missing,"季度",  true);
11 pivotTable.AddFields( Type.Missing, "外協名稱",Type.Missing, true);
12 pivotTable.AddFields( Type.Missing, Type.Missing,"推廣項目", true);
13 PivotField pivotField;
14 //PivotField pivotField2;
15 // pivotField = (PivotField)pivotTable.PivotFields("季度"); //數據透視表的某一字段(左上)
16 // pivotField.Orientation = XlPivotFieldOrientation.xlPageField;
17 //pivotField = (PivotField)pivotTable.PivotFields("外協名稱"); //數據透視表的某一字段(左上)
18 // pivotField.Orientation = XlPivotFieldOrientation.xlPageField;
19 //字段在指定的數據透視表中的位置xlHidden,xlRowField行,xlColumnField列,xlPageField篩選,xlDataField統計 
20 //pivotField = (PivotField)pivotTable.PivotFields(7); //數據透視表的某一字段(右上)
21 //pivotField.Orientation = XlPivotFieldOrientation.xlColumnField;
22 //pivotField = (PivotField)pivotTable.PivotFields(8); //數據透視表的某一字段(左下)
23 //pivotField.Orientation = XlPivotFieldOrientation.xlRowField;
24 pivotField = (PivotField)pivotTable.PivotFields("供應商評估(十分制)"); //數據透視表的某一字段(右下)
25 pivotField.Orientation = XlPivotFieldOrientation.xlDataField;
26 pivotField.Function = XlConsolidationFunction.xlAverage; //返回或設置對數據透視表字段彙總時所使用的函數
27 }
View Code

四、結束進程

結束進程能夠結束指定進程,也能夠結束全部進程:

 1 private void KillExcelProceed()//結束全部進程
 2 {
 3 System.Diagnostics.Process[] ExcelProcesses;
 4 ExcelProcesses = System.Diagnostics.Process.GetProcessesByName("EXCEL");
 5 foreach (System.Diagnostics.Process IsProcedding in ExcelProcesses)
 6 {
 7       if (IsProcedding.ProcessName == "EXCEL")
 8       {
 9           IsProcedding.Kill();
10       }
11 }
12 }
13 [System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
14 private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
15 private void Kill(Application excel)//結束指定excel進程
16 {
17 IntPtr t = new IntPtr(excel.Hwnd); //獲得這個句柄,具體做用是獲得這塊內存入口 
18 int k = 0;
19 GetWindowThreadProcessId(t, out k); //獲得惟一標誌k
20 System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k); //k的引用
21 p.Kill(); //關閉k
22 }
View Code

五、 數據寫入

數據寫入也有兩種方法:

(1)第一種是直接寫入,不過若是有空數據則有可能報錯:

wsheet1.Cells[i, j].value = wsheet2.Cells[x, y].value;

(2)第二種是用copy函數將數據總體複製,至關於手動選擇數據區域,複製到另外一塊區域:

 1 public static void CopyData(Worksheet worksheet, Worksheet sheetsource)
 2         {
 3             int src = sheetsource.UsedRange.Rows.Count;
 4             int scc = sheetsource.UsedRange.Columns.Count;
 5             int drc = worksheet.UsedRange.Rows.Count;
 6 
 7             Range range = sheetsource.Range[sheetsource.Cells[3, 1], sheetsource.Cells[src, scc]];
 8             range.Copy(Type.Missing);//複製數據
 9             Range range1 = worksheet.Range[worksheet.Cells[drc+1, 1], worksheet.Cells[drc + src-1, scc]];
10             worksheet.Paste(range1, false);//粘貼數據
11 
12         }
View Code

(3)數據排序

像第一種一條一條寫入數據,有時能夠將數據先排序而後導入,在特定時候能夠節省不少沒必要要的操做,提升效率:

 1 int a = workSheet.UsedRange.Rows.Count;
 2 int b = workSheet.UsedRange.Columns.Count;
 3 Range myRange = (Range) workSheet.Cells[1, num];
 4 workSheet.Sort.SortFields.Clear();//清除綁定數據(不執行此操做則可能致使屢次排序異常)
 5 workSheet.Sort.SortFields.Add(myRange,XlSortOn.xlSortOnValues,XlSortOrder.xlAscending,Type.Missing,XlSortDataOption.xlSortNormal);
 6 myRange = workSheet.Range[workSheet.Cells[1, 1], workSheet.Cells[a, b]];
 7 workSheet.Sort.SetRange(myRange);
 8 workSheet.Sort.Header = XlYesNoGuess.xlYes; //第一行或列是否包含頭信息
 9 workSheet.Sort.MatchCase = false; //區分大小寫
10 workSheet.Sort.Orientation = XlSortOrientation.xlSortColumns; //行或列排序
11 workSheet.Sort.SortMethod = XlSortMethod.xlPinYin; //英文或中文排序
12 workSheet.Sort.Apply(); //執行排序
View Code

六、其餘的一些操做

觸發事件和禁止觸發事件:

(1)觸發事件(這是寫在thisaddin_startup中的括號裏面爲觸發函數,即當觸發某一事件時,調用函數):

1 Globals.ThisAddIn.Application.SheetSelectionChange += new Excel.AppEvents_SheetSelectionChangeEventHandler(Application_SheetSelectionChange);//點擊單元格觸發事件
2 Globals.ThisAddIn.Application.SheetChange += new Excel.AppEvents_SheetChangeEventHandler(Application_SheetChange);//修改內容觸發事件
3 Globals.ThisAddIn.Application.SheetPivotTableUpdate += new Excel.AppEvents_SheetPivotTableUpdateEventHandler(Application_SheetPivotTableUpdate);//數據透視表更新觸發事件
4 Globals.ThisAddIn.Application.SheetCalculate += new Excel.AppEvents_SheetCalculateEventHandler(Application_SheetCalculate);//對工做表進行從新計算以後
5 Globals.ThisAddIn.Application.SheetBeforeRightClick += new Excel.AppEvents_SheetBeforeRightClickEventHandler(Application_SheetBeforeRightClick); //右鍵單擊工做表時觸發事件
6 Globals.ThisAddIn.Application.SheetFollowHyperlink+= new Excel.AppEvents_SheetFollowHyperlinkEventHandler(Application_SheetFollowHyperlink );//單擊工做表上的任意超連接時
7 Globals.ThisAddIn.Application.SheetActivate += new Excel.AppEvents_SheetActivateEventHandler(Application_SheetActivate);//激活工做表
8 void Application_SheetSelectionChange(object sender, Excel.Range range){}//點擊單元格觸發事件函數
9 void Application_SheetActivate(object sender){}//激活工做表函數
View Code

(2)禁止觸發事件(觸發事件是全局的,因此在特定時刻不須要觸發事件時要將其禁止):

1 Globals.ThisAddIn.Application.ScreenUpdating = false; //防止屏幕閃動
2 Globals.ThisAddIn.Application.EnableEvents = false;//禁止觸發事件
3 Globals.ThisAddIn.Application.DisplayAlerts = false;//禁彈窗
4 Globals.ThisAddIn.Application.DisplayAlerts = true;//啓彈窗
5 Globals.ThisAddIn.Application.ScreenUpdating = true; //啓動屏幕閃動
6 Globals.ThisAddIn.Application.EnableEvents = true;//啓動觸發事件
View Code

七、  錯誤

(1)     在開發過程當中,不可避免會出現一些bug和錯誤,調試運行的時候致使進程卡死的狀況也有可能,次數多了,excel會自動禁用你調試出錯的加載項。解決方法是:文件——選項,在彈出框最下方中間偏左下拉框選擇「禁用項目」,點擊「轉到」,將被禁用的加載項啓用,而後在「開發工具」選項卡點擊「com加載項」,勾選你的項目名稱,肯定,加載項就出來了,又能夠一塊兒快樂的玩耍了!

還有「異常來自 HRESULT:0x800A03EC」這種錯誤,通常是代碼有錯誤,具體緣由視狀況而定。(已遇到由於從0開始循環拋異常和由於透視表表格格式不一樣而使用pivotField.PivotFilters.Add時拋異常)

(2)     在卸載舊的addin時可能會未卸載乾淨,這就須要在註冊表中刪除,註冊表位置:HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\

八、參考

淺談Excel開發:三 Excel 對象模型:

http://www.cnblogs.com/yangecnu/p/3247234.html

C#開發Excel報表系列整理:

http://www.360doc.com/content/07/0824/10/12027_691547.shtml

VSTO學習歸結:

http://club.excelhome.net/forum.php?mod=viewthread&tid=896478&extra=page%3D1

工做簿工做表全部事件一覽表:

http://club.excelhome.net/thread-71744-1-1.html

相關文章
相關標籤/搜索