C# ExcelAddIn 开发笔记

时间:2024-02-18 13:02:29

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