標籤:
好久都沒有寫部落格了,最近真的是太忙了,接手公司要做的一個小的新的項目,從接觸認識到一個新東西,再到自己琢磨研究,最終結合公司業務把整個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~~~~~~~~~~~~
C# ExcelAddIn 開發筆記