好久都没有写博客了,最近真的是太忙了,接手公司要做的一个小的新的项目,从接触认识到一个新东西,再到自己琢磨研究,最终结合公司业务把整个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~~~~~~~~~~~~