C# ExcelAddIn 開發筆記


好久都沒有寫博客了,最近真的是太忙了,接手公司要做的一個小的新的項目,從接觸認識到一個新東西,再到自己琢磨研究,最終結合公司業務把整個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~~~~~~~~~~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM