1. 程式人生 > >C#使用NPOI讀寫excel

C#使用NPOI讀寫excel

    NPOI作為POI專案的.NET 版本,確實是能很方便的實現讀寫Excel,那麼本文就作為科普,從頭到尾實現以下通過NOPI 讀寫Excel吧!

    首先需要下載NOPI,這裡是連結,下載最新版本就行http://npoi.codeplex.com/releases

 本人下載的是2.1.3版本解壓開啟後

                                         

進入dotnet4就能找到我們需要的dll檔案,我測試時使用的環境是vs2010通過新增引用的方式,把dll檔案新增進工程就可以,當然只是簡單的讀寫Excel的話就不需要把所有的dll檔案都新增進來,我只添加了三個

      

在這裡為了方便演示我使用winform,同時添加了一個控制元件farpoint spread,關於這種控制元件的新增就不詳細說明了,在網上搜索就能找到新增後的結果如下

           

OK,接下來實現的就是各個按鈕的功能了,通過NOPI讀取資料主要是在第一個按鈕中實現,因此我只把第一的按鈕的程式碼寫上吧!

private void button1_Click(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                this.textBox1.Text = this.openFileDialog1.FileName;
                TestExcelRead(this.openFileDialog1.FileName.Replace("\\","//"));//把"\"換成"//"
            }
        }
    可以看出,主要用了一個函式,那麼我就來看看這個函式的實現
</pre><pre name="code" class="csharp">private  void TestExcelRead(string file)
        {
            try
            {
                using (ExcelHelper excelHelper = new ExcelHelper(file))
                {
                    //第一引數:excel分頁名,第二個引數第一行是否是列名
                    DataTable dt = excelHelper.ExcelToDataTable("MySheet",false);
                    this.ShowData(dt);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception: " + ex.Message);
            }
        }

當然這裡用了一個ExcelHelper類例項化了一個物件excelHelper,我們稍後再說這個類的實現我們還呼叫了一個ShowData函式用來在Spread上顯示函式非常簡單
 private void ShowData(DataTable data)
        {
            if (data == null) return;
            for (int i = 0; i < data.Rows.Count; ++i)
            {
                for (int j = 0; j < data.Columns.Count; ++j)
                {
                    this.fpSpread1_Sheet1.Cells[i, j].Text = data.Rows[i][j].ToString();
                }
            }
        }
就是將DataTable的資料寫到我們的控制元件中而已,接下來我們來看看核心的也就是ExcelHelper類
 class ExcelHelper:IDisposable
    {
        private string fileName = null; //檔名
        private IWorkbook workbook = null;
        private FileStream fs = null;
        private bool disposed;

        public ExcelHelper(string fileName)
        {
            this.fileName = fileName;
            disposed = false;
        }

         /// <summary>
        /// 將excel中的資料匯入到DataTable中
        /// </summary>
        /// <param name="sheetName">excel工作薄sheet的名稱</param>
        /// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
        /// <returns>返回的DataTable</returns>
        public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)
        {
            ISheet sheet = null;
            DataTable data = new DataTable();
            int startRow = 0;
            try
            {
                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);//讀取檔案
                if (fileName.IndexOf(".xlsx") > 0) // 2007版本
                    workbook = new XSSFWorkbook(fs);
                else if (fileName.IndexOf(".xls") > 0) // 2003版本
                    workbook = new HSSFWorkbook(fs);

                if (sheetName != null)
                {
                    sheet = workbook.GetSheet(sheetName);//獲取檔案的分頁
                    if (sheet == null) //如果沒有找到指定的sheetName對應的sheet,則嘗試獲取第一個sheet
                    {
                        sheet = workbook.GetSheetAt(0);
                    }
                }
                else
                {
                    sheet = workbook.GetSheetAt(0);
                }
                if (sheet != null)
                {
                    int k = 0, cellCount = 0;
                    IRow firstRow = sheet.GetRow(0);//獲取第一行
                    while (firstRow == null)
                    {
                        firstRow = sheet.GetRow(++k);//排除空行,找到第一個有字元的行
                    }


                    if (isFirstRowColumn)//第一行是列名
                    {
                        cellCount = firstRow.LastCellNum; //一行最後一個cell的編號 即總的列數

                        for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
                        {
                            ICell cell = firstRow.GetCell(i);
                            if (cell != null)
                            {
                                string cellValue = cell.StringCellValue;
                                if (cellValue != null)
                                {
                                    DataColumn column = new DataColumn(cellValue);
                                    data.Columns.Add(column);
                                }
                            }
                        }
                        startRow = sheet.FirstRowNum + 1;
                    }
                    else// 第一行不是列名
                    {
                        int max = 0;
                        for (int i = sheet.FirstRowNum; i <= sheet.LastRowNum; i++)// 找到所有行中最多字元
                        {
                            if (sheet.GetRow(i) == null)
                                continue;

                            max = (sheet.GetRow(i).LastCellNum > max) ? sheet.GetRow(i).LastCellNum : max;
                        }
                        cellCount = max;
                        for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
                        {
                            DataColumn column = new DataColumn();
                            data.Columns.Add(column);
                        }
                        startRow = sheet.FirstRowNum;
                    }

                    //最後一列的標號
                    int rowCount = sheet.LastRowNum;

                    for (int i = startRow; i <= rowCount; ++i)//將從檔案中獲取的資料儲存到DataTable中
                    {
                        IRow row = sheet.GetRow(i);

                        if (row == null)
                        {
                            continue; //沒有資料的行預設是null
                        }

                        DataRow dataRow = data.NewRow();
                        for (int j = row.FirstCellNum; j < cellCount; ++j)
                        {
                            if (row.GetCell(j) != null) //同理,沒有資料的單元格都預設是null
                                dataRow[j] = row.GetCell(j).ToString();
                        }

                        data.Rows.Add(dataRow);
                    }
                }
                
                return data;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception: " + ex.Message);
                return null;
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (fs != null)
                        fs.Close();
                }

                fs = null;
                disposed = true;
            }
        }
自此主要功能以闡述完畢,以下結果

      

不足:此程式碼對於各種情況的判斷考慮的還不是很到位,例如空檔案應該報錯,由於時間比較緊,所以先寫這些,還有spread這個控制元件還有Bug在這隻作為演示之用!