C#學習日記2017-04-22 NPOI用法小結(未完待續)

NPOI基礎

認識NPOI:

NPOI能夠在用戶沒有安裝office情況下仍然能夠操作office對象,是POI 的.net版本。可支持的文件格式有.xls .doc .ppt等。在大多數要運用到Excel的情況下,優先考慮使用NPOI操作Excel文件。而不是直接利用C#操作Excel。

NPOI的優點:

NPOI的優點在於:

  1. 即使本地計算機上沒有安裝Office,NPOI仍可生產和操作Excel文件。不必擔心Office版本和適應性問題
  2. 使用面向接口的設計,NPOI開發人員封裝了Excel的很多有用的操作,我們僅需要知道某個功能怎麼用,而不需要知道這個功能的具體實現
  3. NPOI是完全免費的,感謝NPOI開發團隊的無私奉獻,由於他們不斷的進行更新升級。我們才得以擁有一款操作Excel的神器。

其他方式操作Excel的缺點:

  1. 通過OleDB讀取Excel:使用Microsoft Jet 提供程序用於連接到 Excel工作簿讀取數據。這種方法將Excel文件視
    爲一個數據源,可以使用SQL語句進行鏈接操作,也不需要安裝Office,
    但是使用這種方法只能夠進行簡單的的讀 寫操作,稍微複雜的操作使用OleDB無法完成(如單元格合併,着色等)。

  2. 調用Com組件操作Excel:使用該方法需要先引入Microsoft.Office.Interop.Excel,可以利用VSTO(Visual Studio Tools for Office)輕鬆調用Com組件完成Excel操作。但是如果是Web站點部署在IIS上時,要求服務器已安裝了Excel,有時候還需要爲配置IIS權限。最重要的一點是Com組件操作Excel基於單元格方式讀取的,所以在讀取數據很慢。大量操作數據的時候並不建議使用這種方式。

NPOI結構

NPOI2.0版本結構:

NPOI 2.0有幾個DLL構成,他們分別是

NPOI.DLL,

NPOI.OOXML.DLL,

NPOI.OpenXml4Net.dll,

NPOI.OpenXmlFormats.dll,其中後三個是2.0新加的庫。

NPOI.DLL中包含的模塊

NPOI.Util 基礎輔助庫
NPOI.POIFS OLE2格式讀寫庫,主要負責處理DocumentInformation
NPOI.DDF Microsoft Drawing格式讀寫庫
NPOI.SS Excel 2003和Excel 2007操作庫共用的接口庫以及公用模塊實現,如公式計算庫
NPOI.HPSF OLE2的Summary Information和Document Summary Information屬性讀寫庫
NPOI.HSSF Excel BIFF格式讀寫庫,這是用戶用的最多的命名空間

NPOI.OOXML中包含的模塊

NPOI.XSSF Excel 2007操作庫,大部分對象都實現了NPOI.SS的接口
NPOI.XWPF Word 2007操作庫

NPOI.OpenXml4Net.DLL中包含的模塊

只有一個,即NPOI.OpenXml4Net,它是從POI的子項目OpenXml4j移植過來的,其功能類似於NPOI.POIFS,只是它操作的是OOXML格式。這個模塊和微軟提供的System.Packaging功能是一致的,只是System.Packaging支持.Net 3.0以上,這個支持.NET 2.0。

NPOI.OpenXmlFormats.DLL中包含的模塊

也只有一個,即OpenXmlFormats,它定義了所有OOXML對象和C#對象的映射關係,並協助進行序列化和反序列化,從而使文件讀寫層和邏輯層分離。

NPOI操作

NPOI創建並操作Excel文件

添加引用

using NPOI.HSSF.UserModel;           //最常用的引用,可以操作excel 2003 的.xls文件
using NPOI.XSSF.UserModel;           //操作excel 2007的.xlsx文件
using ICSharpCode.SharpZipLib.Zip;   //引用這個可以實現文件的壓縮和解壓縮
using NPOI.SS.UserModel;             //包括xls和xlsx共用的接口庫和公用模式的實現
using System.IO;

創建工作簿,工作表,行,單元格

            IWorkbook book1 = new HSSFWorkbook();        //創建了一個xls格式的工作簿
            IWorkbook book2 = new XSSFWorkbook();       //創建了一個xlsx格式的工作簿


            ISheet sheet1 = book1.CreateSheet();          //創建一個工作表
            ISheet sheet2 = book1.CreateSheet("sheet1"); //創建一個帶名稱的工作表


            IRow row = sheet1.CreateRow(0);              //創建工作表內的一行
            ICell cell = row.CreateCell(0);              //創建工作表內一行的單元格

            //讀取一個Excel表,path是文件路徑
            FileStream fileExcel = new FileStream(path,FileMode.Open,FileAccess.Read); 

            IWorkbook book1 = new HSSFWorkbook(fileExcel);    //創建了一個xls格式的工作簿,並填充工作簿
            ISheet sheet = book1.GetSheetAt(0);               //獲取工作簿的第一張表
            IRow row = sheet.GetRow(0);               //獲取工作表的第一行
            ICell cell = row.CreateCell(0);           //獲取一行數據的單元格的值

NPOI實例

DataTable轉換Excel文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Odbc;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.Data;
using System.IO;


namespace PackageManagement
{
    public class ExcelHelper
    {
        readonly int ecxelRowMax = 65536;  //設置excel的最大行數
        public byte[] mDataTable2Excel(DataTable dt, string SheetName)   //將datatable轉換成Excel,並返回一個字節數組 
        {
            IWorkbook book = new HSSFWorkbook();                         //定義一個工作簿

            if (dt.Rows.Count < ecxelRowMax)                             //如果表的行數沒超過最大值。
            {
                mDataWrite2Sheet(dt, 0, dt.Rows.Count - 1, book, SheetName);  //調用方法創建表格
            }
            else                                                         //超過一張表的最大數,進行分表存儲
            {
                int page = dt.Rows.Count / ecxelRowMax;
                for (int i = 0; i < page; i++)                           //循環頁數,創建表格
                {
                    int iStartRow = i * ecxelRowMax;                           //獲取分表起始索引值
                    int iEndRow = (i * ecxelRowMax) + ecxelRowMax - 1;         //獲取分表結束索引值
                    mDataWrite2Sheet(dt, iStartRow, iEndRow, book, SheetName); //調用方法創建表格
                }

                mDataWrite2Sheet(dt, page * ecxelRowMax - 1, (dt.Rows.Count), book, SheetName);  //分表剩餘不足一頁的部分也創建一張表

            }

            MemoryStream ms = new MemoryStream();   //創建內存流對象
            book.Write(ms);                         //將book工作簿的內容寫到MemoryStream中
            return ms.ToArray();                    //返回一個字節流數組
        }

        private void mDataWrite2Sheet(DataTable dt, int startRow, int endRow, IWorkbook book, string sheetName)
        {
            ISheet sheet = book.CreateSheet();          //創建一個工作簿
            IRow header = sheet.CreateRow(0);           //創建工作簿的第一行,默認它爲標題行
            for (int i = 0; i < dt.Columns.Count; i++)  //循環建立標題行
            {
                ICell cell = header.CreateCell(i);      //創建標題行的單元格
                string value = dt.Columns[i].Caption ?? dt.Columns[i].ColumnName;  //獲取列名
                cell.SetCellValue(value);               //單元格賦值datatable的列名
            }
            int indexRow = 1;
            for (int i = startRow; i < endRow; i++)     //循環行的數據
            {
                DataRow dr = dt.Rows[i];                //新建一個datarow對象
                IRow row = sheet.CreateRow(indexRow++); //創建工作表的Row對象

                for (int j = 0; j < dr.ItemArray.Length; j++)         //循環單元格的數據
                {
                    row.CreateCell(j).SetCellValue(dr[j].ToString()); //向行對象row中添加單元格數據
                }   
    }
 }

excel文件轉換DataTable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Odbc;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.Data;
using System.IO;


namespace PackageManagement
{
    public class ExcelHelper
    {
        //讀取數據
        public DataTable mExcel2DataTable(string path)   //將excel轉換成datatable
        {
            DataTable dt = new DataTable();    //定義一個DataTable表
            DataColumn dc = new DataColumn();  //定義一個DataColumn列
            ISheet sheet = null;               //聲明一個工作表
            IWorkbook book = null;             //聲明一個工作簿

            try
            {
                FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);  //用文件流讀取Excel文件
                book = new HSSFWorkbook(fs);   //獲取流文件轉換成工作簿對象
            }
            catch (Exception ex)
            {
                throw ex;               //拋出表佔用問題
            }      



            if (book.NumberOfSheets <= 1)  //Excel只存在一張表格
            {

                sheet = book.GetSheetAt(0);           //獲取第一個表格
                MFillDataTable(book, sheet, dc, dt);  //調用方法轉換成DataTable表

            }
            else                            //Excel有多個表格
            {
                for (int i = 0; i < book.NumberOfSheets; i++)  //循環表的數目
                {
                    sheet = book.GetSheetAt(i);                //獲取多張表格
                    MFillDataTable(book, sheet, dc, dt);       //調用方法轉換成DataTable表
                }
            }
            return dt;
        }

        private void MFillDataTable(IWorkbook book, ISheet sheet, DataColumn dc, DataTable dt)
        {
            if (sheet != null)     //如果表不爲空
            {
                IRow HeaderRow = sheet.GetRow(0); //獲取表的第一行,標題行

                if (dt.Columns.Count == 0)        //如果datatable的列的數目爲0,則是第一次設置列對象
                {
                    for (int j = HeaderRow.FirstCellNum; j < HeaderRow.LastCellNum; j++)  //循環標題行的單元格
                    {
                        if (HeaderRow.Cells[j] != null)
                        {
                            string str = HeaderRow.Cells[j].ToString();
                            dc = new DataColumn(str);
                            dt.Columns.Add(dc);           //添加列到datatable中
                        }
                    }
                }

                for (int n = 1; n <= sheet.LastRowNum; n++)   //循環行的數據
                {
                    IRow row = sheet.GetRow(n);               //獲取工作表的行數據
                    if (row != null)                          //行不爲空
                    {
                        DataRow dr = dt.NewRow();             
                        for (int m = row.FirstCellNum; m < row.LastCellNum; m++) //循環行的單元格數據
                        {
                            dr[m] = row.Cells[m].ToString();
                        }
                        dt.Rows.Add(dr.ItemArray);        //填充數據表
                    }
                }
            }
        }
    }
}

“`

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章