1. 程式人生 > >C# 中 NPOI 庫讀寫 Excel 文件的方法【摘】

C# 中 NPOI 庫讀寫 Excel 文件的方法【摘】

prot case enter this num ack npoi 工作薄 解鎖

原作:淡水網誌

NPOI 是開源的 POI 項目的.NET版,可以用來讀寫Excel,Word,PPT文件。在處理Excel文件上,NPOI 可以同時兼容 xls 和 xlsx。官網提供了一份 Examples,給出了很多應用場景的例子,打包好的二進制文件類庫,也僅有幾MB,使用非常方便。

讀Excel

NPOI使用HSSFWorkbook類來處理xls,XSSFWorkbook類來處理xlsx,它們都繼承接口IWorkbook,因此可以通過IWorkbook來統一處理xls和xlsx格式的文件。

以下是簡單的例子

 1         /// <summary>
 2         ///
讀取excel文件 3 /// </summary> 4 /// <param name="filePath">文件路徑</param> 5 public void ReadFromExcelFile(string filePath) 6 { 7 IWorkbook wk = null; 8 string extension = System.IO.Path.GetExtension(filePath); 9 try 10 {
11 FileStream fs = File.OpenRead(filePath); 12 if (extension.Equals(".xls")) 13 { 14 //把xls文件中的數據寫入wk中 15 wk = new HSSFWorkbook(fs); 16 } 17 else 18 { 19 //
把xlsx文件中的數據寫入wk中 20 wk = new XSSFWorkbook(fs); 21 } 22 23 fs.Close(); 24 //讀取當前表數據 25 ISheet sheet = wk.GetSheetAt(0); 26 27 IRow row = sheet.GetRow(0); //讀取當前行數據 28 //LastRowNum 是當前表的總行數-1(註意) 29 30 string text = string.Empty; 31 for (int i = 0; i <= sheet.LastRowNum; i++) 32 { 33 row = sheet.GetRow(i); //讀取當前行數據 34 if (row != null) 35 { 36 //LastCellNum 是當前行的總列數 37 for (int j = 0; j < row.LastCellNum; j++) 38 { 39 //讀取該行的第j列數據 40 string value = row.GetCell(j).ToString(); 41 //Console.Write(value.ToString() + " "); 42 text = text + value.ToString() + "\r\n"; 43 } 44 //Console.WriteLine("\n"); 45 } 46 } 47 SetText(text); 48 } 49 50 catch (Exception e) 51 { 52 //只在Debug模式下才輸出 53 //Console.WriteLine(e.Message); 54 this.textBox1.Text = e.Message; 55 } 56 }

Excel中的單元格是有不同數據格式的,例如數字,日期,字符串等,在讀取的時候可以根據格式的不同設置對象的不同類型,方便後期的數據處理。

 1 //獲取cell的數據,並設置為對應的數據類型
 2 public object GetCellValue(ICell cell)
 3 {
 4     object value = null;
 5     try
 6     {
 7         if (cell.CellType != CellType.Blank)
 8         {
 9             switch (cell.CellType)
10             {
11                 case CellType.Numeric:
12                     // Date comes here
13                     if (DateUtil.IsCellDateFormatted(cell))
14                     {
15                         value = cell.DateCellValue;
16                     }
17                     else
18                     {
19                         // Numeric type
20                         value = cell.NumericCellValue;
21                     }
22                     break;
23                 case CellType.Boolean:
24                     // Boolean type
25                     value = cell.BooleanCellValue;
26                     break;
27                 case CellType.Formula:
28                     value = cell.CellFormula;
29                     break;
30                 default:
31                     // String type
32                     value = cell.StringCellValue;
33                     break;
34             }
35         }
36     }
37     catch (Exception)
38     {
39         value = "";
40     }
41     return value;
42 }

特別註意的是CellType中沒有Date,而日期類型的數據類型是Numeric,其實日期的數據在Excel中也是以數字的形式存儲。可以使用DateUtil.IsCellDateFormatted方法來判斷是否是日期類型。

有了GetCellValue方法,寫數據到Excel中的時候就要有SetCellValue方法,缺的類型可以自己補。

 1 //根據數據類型設置不同類型的cell
 2 public static void SetCellValue(ICell cell, object obj)
 3 {
 4     if (obj.GetType() == typeof(int))
 5     {
 6         cell.SetCellValue((int)obj);
 7     }
 8     else if (obj.GetType() == typeof(double))
 9     {
10         cell.SetCellValue((double)obj);
11     }
12     else if (obj.GetType() == typeof(IRichTextString))
13     {
14         cell.SetCellValue((IRichTextString)obj);
15     }
16     else if (obj.GetType() == typeof(string))
17     {
18         cell.SetCellValue(obj.ToString());
19     }
20     else if (obj.GetType() == typeof(DateTime))
21     {
22         cell.SetCellValue((DateTime)obj);
23     }
24     else if (obj.GetType() == typeof(bool))
25     {
26         cell.SetCellValue((bool)obj);
27     }
28     else
29     {
30         cell.SetCellValue(obj.ToString());
31     }
32 }

cell.SetCellValue()方法只有四種重載方法,參數分別是string, bool, DateTime, double, IRichTextString
設置公式使用cell.SetCellFormula(string formula)

寫Excel

以下是簡單的例子,更多信息可以參見官網提供的Examples。

 1 public void WriteToExcel(string filePath)
 2 {
 3     //創建工作薄  
 4     IWorkbook wb;
 5     string extension = System.IO.Path.GetExtension(filePath);
 6     //根據指定的文件格式創建對應的類
 7     if (extension.Equals(".xls"))
 8     {
 9         wb = new HSSFWorkbook();
10     }
11     else
12     {
13         wb = new XSSFWorkbook();
14     }
15     ICellStyle style1 = wb.CreateCellStyle();//樣式
16     style1.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平對齊方式
17     style1.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直對齊方式
18     //設置邊框
19     style1.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
20     style1.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
21     style1.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
22     style1.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
23     style1.WrapText = true;//自動換行
24     ICellStyle style2 = wb.CreateCellStyle();//樣式
25     IFont font1 = wb.CreateFont();//字體
26     font1.FontName = "楷體";
27     font1.Color = HSSFColor.Red.Index;//字體顏色
28     font1.Boldweight = (short)FontBoldWeight.Normal;//字體加粗樣式
29     style2.SetFont(font1);//樣式裏的字體設置具體的字體樣式
30     //設置背景色
31     style2.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
32     style2.FillPattern = FillPattern.SolidForeground;
33     style2.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
34     style2.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平對齊方式
35     style2.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直對齊方式
36     ICellStyle dateStyle = wb.CreateCellStyle();//樣式
37     dateStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平對齊方式
38     dateStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直對齊方式
39     //設置數據顯示格式
40     IDataFormat dataFormatCustom = wb.CreateDataFormat();
41     dateStyle.DataFormat = dataFormatCustom.GetFormat("yyyy-MM-dd HH:mm:ss");
42     //創建一個表單
43     ISheet sheet = wb.CreateSheet("Sheet0");
44     //設置列寬
45     int[] columnWidth = { 10, 10, 20, 10 };
46     for (int i = 0; i < columnWidth.Length; i++)
47     {
48         //設置列寬度,256*字符數,因為單位是1/256個字符
49         sheet.SetColumnWidth(i, 256 * columnWidth[i]);
50     }
51     //測試數據
52     int rowCount = 3, columnCount = 4;
53     object[,] data = {
54         {"列0", "列1", "列2", "列3"},
55         {"", 400, 5.2, 6.01},
56         {"", true, "2014-07-02", DateTime.Now}
57         //日期可以直接傳字符串,NPOI會自動識別
58         //如果是DateTime類型,則要設置CellStyle.DataFormat,否則會顯示為數字
59     };
60     IRow row;
61     ICell cell;
62     
63     for (int i = 0; i < rowCount; i++)
64     {
65         row = sheet.CreateRow(i);//創建第i行
66         for (int j = 0; j < columnCount; j++)
67         {
68             cell = row.CreateCell(j);//創建第j列
69             cell.CellStyle = j % 2 == 0 ? style1 : style2;
70             //根據數據類型設置不同類型的cell
71             object obj = data[i, j];
72             SetCellValue(cell, data[i, j]);
73             //如果是日期,則設置日期顯示的格式
74             if (obj.GetType() == typeof(DateTime))
75             {
76                 cell.CellStyle = dateStyle;
77             }
78             //如果要根據內容自動調整列寬,需要先setCellValue再調用
79             //sheet.AutoSizeColumn(j);
80         }
81     }
82     //合並單元格,如果要合並的單元格中都有數據,只會保留左上角的
83     //CellRangeAddress(0, 2, 0, 0),合並0-2行,0-0列的單元格
84     CellRangeAddress region = new CellRangeAddress(0, 2, 0, 0);
85     sheet.AddMergedRegion(region);
86     try
87     {
88         FileStream fs = File.OpenWrite(filePath);
89         wb.Write(fs);//向打開的這個Excel文件中寫入表單並保存。  
90         fs.Close();
91     }
92     catch (Exception e)
93     {
94         Debug.WriteLine(e.Message);
95     }
96 }

如果想要設置單元格為只讀或可寫,可以參考這裏,方法如下:

1 ICellStyle unlocked = wb.CreateCellStyle();
2 unlocked.IsLocked = false;//設置該單元格為非鎖定
3 cell.SetCellValue("未被鎖定");
4 cell.CellStyle = unlocked;
5 ...
6 //保護表單,password為解鎖密碼
7 //cell.CellStyle.IsLocked = true;的單元格將為只讀
8 sheet.ProtectSheet("password");

cell.CellStyle.IsLocked 默認就是true,因此sheet.ProtectSheet("password")一定要執行,才能實現鎖定單元格,對於不想鎖定的單元格,就一定要設置cellCellStyle中的IsLocked = false

C# 中 NPOI 庫讀寫 Excel 文件的方法【摘】