NPOI
NPOI中N指代的是.Net,POI是一個完全開源的Java寫成的庫,能夠在沒有安裝微軟Office或者相應環境的情況下讀寫Excel、Word等微軟OLE2元件文件,幾乎支援所有的Office97~Office2007的檔案格式。所以NPOI就是POI專案的.Net版本。目前NPOI的最新版本是今年5月份釋出的V2.2.1,包含了.Net Framework2和.Net Framework4兩個版本。
特點
NPOI 是一個能夠快速讀取與產生Excel檔案的第三方套件,幫助程式開發人員在無安裝Microsoft Office的環境下讀寫Office 97-2003的文件,對於需要產生Excel報表非常好用。NPOI支援的檔案格式處理xls、xlsx外,還包括doc、ppt、vsd等,功能強大。
使用方式
NPOI可透過兩種方式匯出Excel,一是使用Template,將Excel格式拉好存檔,透過NPOI讀取格式後,再將資料填入並另存新檔。
一、EXCEL 分頁
使用前,請引用以下內容
1 2 3 4
| using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; using NPOI.XSSF.UserModel; using System.IO;
|
1.1 HSSF vs XSSF
HSSF中,是使用於2007之前的xls版本。XSSF中,適用於2007及其之後的xlsx版本。
雖然HSSF 只能使用(.xls) ,但可以得知XSSF 是可以使用(.xls),但可能因為版本問題格式、內容有可能會被損毀。
以下程式新建一個Excel 2003 xls和一個2007 xlsx檔案,跟用Office建立的標準Excel格式一樣,每一個Excel檔案初始包含了3個工作表。
以下範例針對顯示分頁內容作排序,當然可以做自訂選擇排序,請讀者自行測試。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Page { public string Name { get; set; } public int Order { get; set; } }
public void NPOIprintf() { List<Page> pages = new List<Page> { new Page { Name = "Sheet1", Order= 1 }, new Page { Name = "Sheet2", Order= 2 }, new Page { Name = "Sheet3", Order= 3 }, };
HSSFWorkbook workbook2003 = HSSFCreateSheet(pages); XSSFWorkbook workbook2007 = XSSFCreateSheet(pages);
Write(workbook2003, @"F:\NPOI_Excel\Excel2003.xls"); Write(workbook2007, @"F:\NPOI_Excel\Excel2007.xls"); }
|
以下函示範例請自行取用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| private static XSSFWorkbook XSSFCreateSheet(List<Page> datas) { if (datas == null) { return null; } XSSFWorkbook _XSSF = new(); IEnumerable<Page> pages = datas.OrderBy(row => row.Order); foreach (Page result in pages) { _XSSF.CreateSheet(result.Name); } return _XSSF; }
private static HSSFWorkbook HSSFCreateSheet(List<Page> datas) { if (datas == null ) { return null; } HSSFWorkbook _HSSF = new(); IEnumerable<Page> pages = datas.OrderBy(row => row.Order); foreach(Page result in pages) { _HSSF.CreateSheet(result.Name); } return _HSSF; }
private static void Write(HSSFWorkbook HSSF,string FilePath , string Data="") { FileStream file = new (FilePath, FileMode.Create); HSSF.Write(file); file.Close(); HSSF.Close(); }
private static void Write(XSSFWorkbook XSSF, string FilePath, string Data = "") { FileStream file = new(FilePath, FileMode.Create); XSSF.Write(file); file.Close(); XSSF.Close(); }
|
二、讀取 Excel
2.1、取得Sheet 名稱
如果要往回抓Sheet 名稱,又不想從 List抓取可以從XSSFWorkbook 、HSSFWorkbook抓取裡面的Sheet Name。
1 2 3 4 5 6 7 8 9 10
| private static void Get_SheetName(XSSFWorkbook Workbook) { int index = 0; while (index < Workbook.NumberOfSheets) { string sheet = Workbook.GetSheetName(index); Console.WriteLine("Sheet Name : " + sheet.ToString()); index++; } }
|
2-2 讀取 Excel 檔案資料
寫資料要遵循一定的順序,可以概括為:
- 讀取(或新建一個工作簿)
- 獲取工作表
- 對工作表新增行
- 對每一行新增單元格
- 對單元格賦值
1 2 3 4 5 6 7 8 9 10 11 12 13
| public void NPOIRead() { ISheet sheet = ReadSheetAt(@"F:\NPOI_Excel\Excel2007.xlsx", 0); for (int i = 0; i <= sheet.LastRowNum; i++) { if (sheet.GetRow(i) == null) { continue; } foreach (ICell cell in sheet.GetRow(i)) { Console.WriteLine(cell); } } }
|
ReadSheetAt 內容主要決定使用哪種版本(xls、xlsx),再回傳Sheet 內容。方法可以使用(.NumberOfSheets)將所有Sheet 取出。
1 2 3 4 5 6 7 8 9 10 11 12 13
| private static ISheet ReadSheetAt(string fileName, int index) { FileStream fileStream = new(fileName, FileMode.Open, FileAccess.Read);
IWorkbook workbook = fileName.IndexOf(".xls") > 0 ? new HSSFWorkbook(fileStream) : new XSSFWorkbook(fileStream);
fileStream.Close(); return workbook.GetSheetAt(index); }
|
三、寫入 Excel
3-1 設定測試資料
這邊用一個簡單的測試資料,利用class 方便寫入 excel 欄位。
1 2 3 4 5 6 7 8
| public class Demo { [DisplayName("名稱")] public string name { get; set; }
[DisplayName("日期")] public DateTime date { get; set; } }
|
1 2 3 4
| var data = new List<Demo>(){ new Demo{ name = "test1", date = DateTime.Now }, new Demo{ name = "test2", date = DateTime.Now }, };
|
3-2 寫入 Excel
處理excel 先建立 Workbook,再建立 Sheet,最後建立 Row,再將資料寫入 Cell。
接下來,下載用Steam 方式將資料寫入檔案或下載。
data 是由上面new List<Demo>()
取得的資料。透過data來讓欄位自動生成,而不用一個一個欄位去寫入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = (XSSFSheet)workbook.CreateSheet("Default"); Type header = typeof(Demo);
IRow row = sheet.CreateRow(0); for (int i = 0; i < header.GetProperties().Length; i++) { ICell cell = row.CreateCell(i); cell.SetCellValue(header.GetProperties()[i].GetCustomAttribute<DisplayNameAttribute>().DisplayName); }
for (int i = 0; i < data.Count; i++) { IRow row = sheet.CreateRow(i + 1); for (int j = 0; j < header.GetProperties().Length; j++) { ICell cell = row.CreateCell(j); cell.SetCellValue(header.GetProperties()[j].GetValue(data[i]).ToString()); } }
FileStream file = new FileStream(@"F:\NPOI_Excel\Excel2007.xlsx", FileMode.Create); workbook.Write(file); file.Close(); workbook.Close();
|
四、補充
4-1 隱藏工作表
如果要隱藏工作表,需要對XSSFWorkbook抓取哪個是要隱藏的工作表。
以下範例只針對最後一比工作表進行隱藏。
1 2
| Workbook.SetSheetHidden(Workbook.NumberOfSheets -1 , true);
|