好久都沒有寫博客了,最近真的是太忙了,接手公司要做的一個小的新的項目,從接觸認識到一個新東西,再到自己琢磨研究,最終結合公司業務把整個excel插件項目完成,還是有一點點成就感。以下是項目中基本上大致所有總結的Points:
1.ADO.NET數據庫操作,當然效率還是不是很高,初級水平數據量不是很大,先使用這個。
2.ThisAddin包含的對象,當前活動sheet: Excel.Worksheet worksheet = (Excel.Worksheet)Globals.ThisAddIn.Application.ActiveSheet;
3.excel range對象的各種屬性及方法,如賦值,隱藏,篩選,清除,添加公式等等。
------------------------------------------------------------------------------------------
這里面有個很費勁的東西研究了一上午:”excel工作表的保護“,首先要解除鎖定,然后對於要保護的range鎖定以后再保護。
即用戶在編輯excel的時候不允許編輯公式列。大家可以參考excelhome論壇多學習一下,雖然里面很多都是VBA的內容,翻譯到C#相信不難。
-----------------------------------------------------------------------------------------------------------------------------------------
4.WINFORM窗體回傳值,使用委托,不限於窗體子父窗體傳值,很好用。
5.backgroundWorker1組件使用,達到后台下載或回傳到數據庫操作中,不允許界面操作。
Ribbon的設計器以及業務邏輯:
點擊登陸按鈕,判斷當前sheet是否可用此插件,選擇相應登陸條件(數據源從數據里選出的datatable),並獲取當前AD域用戶值,判斷權限OK之后,回傳到當前Ribbon界面。以備接下來的業務應用。每次登陸之后自動清空當前SHEET的特定內容。
點擊下載按鈕(未登陸不可用)公式列自動初始化excel,從DB->excel,做好excel列字段與DB表字段Mapping之后,使用二維數組對RANGE賦值,效率很高。
<下載和上傳包括兩個表的更新插入,Master表用於保存對於模板內的一些備注和表頭等信息>
用戶在相應登陸條件下編輯excel。
點擊上傳按鈕(未登陸不可用)excel->DB,判斷excel相應字段是否符合要求,NO->提示當前NOcell的行列數,修改之后上傳。
以下是excel模板:
以上是大致業務邏輯。
接下來針對基本大致邏輯的部分代碼,刪去了部分業務,與大家分享。
DB->excel
protected void Fill(System.Data.DataTable dt, int rowStart, int colStart, bool isFormat, int digit) { int p = 50000; for (int beginIndex = 0; beginIndex < dt.Rows.Count; beginIndex += p) { int endIndex = dt.Rows.Count - 1; if (beginIndex + p < dt.Rows.Count) { endIndex = beginIndex + p - 1; } object[,] arr = new object[endIndex - beginIndex + 1, dt.Columns.Count]; for (int i = beginIndex; i <= endIndex; i++) { for (int j = 0; j < dt.Columns.Count; j++) { arr[i - beginIndex, j] = dt.Rows[i][j].ToString().Replace("=", ""); } } Range range = sheet.get_Range(sheet.Cells[rowStart + beginIndex + 1, colStart + 1], sheet.Cells[rowStart + endIndex + 1, colStart + dt.Columns.Count]); range.Value2 = arr; range.Borders.LineStyle = XlLineStyle.xlContinuous; if (isFormat) { string strDigit = string.Empty; for (int k = 0; k < digit; k++) { strDigit += "0"; } if (string.IsNullOrEmpty(strDigit)) { range.NumberFormat = "#,##0.00"; } else { range.NumberFormat = "#,##0." + strDigit; } } else { range.NumberFormat = "#,##0"; } } }
range的各種基本屬性:
range.EntireColumn.Hidden = true;//隱藏列 /// <summary> /// 設置標題行樣式,紅底 /// </summary> /// <param name="dt"></param> /// <param name="sheet"></param> /// <param name="rowCount">設置的行數</param> public void SetTitleStyle(System.Data.DataTable dt, Excel.Worksheet sheet, int rowCount) { if (dt.Rows.Count <= 0 || dt.Columns.Count <= 0) { return; } rngTemp = sheet.get_Range(sheet.Cells[startRowIndex + 1, startColIndex + 1], sheet.Cells[startRowIndex + 1, startColIndex + dt.Columns.Count]); rngTemp.Interior.ColorIndex = 30; rngTemp.Font.ColorIndex = 2; rngTemp.Font.Bold = 1; } //===================================== if (worksheet.ProtectContents)//如果被保護則解除保護 { worksheet.Unprotect("MyPassword");//之前下載過,刪除之前要設置不保護 } Excel.Range range = (Excel.Range)worksheet.get_Range((Excel.Range)worksheet.Cells[startRow, startColumn], (Excel.Range)worksheet.Cells[endRow, endColumn]); range.Select();//選擇要清除的range if (IsDeleteEntireRow) {//是否整行刪除 range.EntireRow.Delete(Excel.XlDeleteShiftDirection.xlShiftUp); } else { //range.Delete(Excel.XlDeleteShiftDirection.xlShiftUp); range2.Cells.ClearContents(); range.Cells.ClearContents();//只清除值 //定位到第一個單元格 Excel.Range range3 = worksheet.get_Range(worksheet.Cells[11, 1], worksheet.Cells[11, 1]); range3.Activate(); }
獲取當前域及用戶名:
private string domainName = System.Environment.UserDomainName;//獲取當前AD域 private string domainUserName = System.Environment.UserName;//獲取當前域用戶名
設置公式及保護:
Excel.Range range2 = worksheet.get_Range(worksheet.Cells[i, 5], worksheet.Cells[i, 5]); if (worksheet.ProtectContents)//如果被保護則解除保護 { worksheet.Unprotect("MyPassword");//之前下載過,刪除之前要設置不保護 } range2.Formula = "=B" + i + "+C" + i + "+D" + i; range2.Locked = false; if (IfProtected) { range2.Locked = true; } ... worksheet.Protect("MyPassword", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
完成圖奉上:
大致就先這樣吧,工作又來了,,,加油!
Fighting~~~~~~~~~~~~