c#使用NPOI進行Excel導入導出,附源碼,vs2010


 

目錄

1. 介紹:描述第三方類庫NPOI以及Excel結構

2. Excel導入:介紹C#如何調用NPOI進行Excel導入,包含:流程圖、NOPI以及C#代碼

3. Excel導出:介紹C#如何調用NPOI進行Excel導出,包含:流程圖、NOPI以、C#代碼以及代碼分析

4. 源碼下載:展示運行圖及源碼下載 

 

1. 介紹

1.1 第三方類庫:NPOI

說明:NPOI是POI項目的.NET 版本,可用於Excel、Word的讀寫操作。

優點:不用裝Office環境。

下載地址:http://npoi.codeplex.com/releases

 

1.2 Excel結構介紹

工作簿(Workbook):每個Excel文件可理解為一個工作簿。

工作表(Sheet):一個工作簿(Workbook)可以包含多個工作表。

行(row):一個工作表(Sheet)可以包含多個行。

 

2. Excel導入

2.1 操作流程

 

2.2 NPOI操作代碼

說明:把Excel文件轉換為List<T>

步驟:

①讀取Excel文件並以此初始化一個工作簿(Workbook);

②從工作簿上獲取一個工作表(Sheet);默認為工作薄的第一個工作表;

③遍歷工作表所有的行(row);默認從第二行開始遍歷,第一行(序號0)為單元格頭部;

④遍歷行的每一個單元格(cell),根據一定的規律賦值給對象的屬性。

代碼:

 

2.3 C#邏輯操作代碼

說明:對Excel轉換后的List<T>進行后續操作;如:檢測有效性、持久化存儲等等

步驟:

①調用2.2代碼,把Excel文件轉換為List<T>。

②對List<T>進行有效性檢測:必填項是否為空、是否有重復記錄等等。

③對List<T>進行持久化存儲操作。如:存儲到數據庫。

④返回操作結果。

代碼:

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public  void  ImportExcel(HttpContext context)
{
     StringBuilder errorMsg =  new  StringBuilder();  // 錯誤信息
     try
     {
 
         #region 1.獲取Excel文件並轉換為一個List集合
 
         // 1.1存放Excel文件到本地服務器
         HttpPostedFile filePost = context.Request.Files[ "filed" ];  // 獲取上傳的文件
         string  filePath = ExcelHelper.SaveExcelFile(filePost);  // 保存文件並獲取文件路徑
 
         // 單元格抬頭
         // key:實體對象屬性名稱,可通過反射獲取值
         // value:屬性對應的中文注解
         Dictionary< string string > cellheader =  new  Dictionary< string string > {
             "Name" "姓名"  },
             "Age" "年齡"  },
             "GenderName" "性別"  },
             "TranscriptsEn.ChineseScores" "語文成績"  },
             "TranscriptsEn.MathScores" "數學成績"  },
         };
 
         // 1.2解析文件,存放到一個List集合里
         List<UserEntity> enlist = ExcelHelper.ExcelToEntityList<UserEntity>(cellheader, filePath,  out  errorMsg);
 
         #endregion
 
         #region 2.對List集合進行有效性校驗
 
         #region 2.1檢測必填項是否必填
 
         for  ( int  i = 0; i < enlist.Count; i++)
         {
             UserEntity en = enlist[i];
             string  errorMsgStr =  "第"  + (i + 1) +  "行數據檢測異常:" ;
             bool  isHaveNoInputValue =  false // 是否含有未輸入項
             if  ( string .IsNullOrEmpty(en.Name))
             {
                 errorMsgStr +=  "姓名列不能為空;" ;
                 isHaveNoInputValue =  true ;
             }
             if  (isHaveNoInputValue)  // 若必填項有值未填
             {
                 en.IsExcelVaildateOK =  false ;
                 errorMsg.AppendLine(errorMsgStr);
             }
         }
 
         #endregion
 
         #region 2.2檢測Excel中是否有重復對象
 
         for  ( int  i = 0; i < enlist.Count; i++)
         {
             UserEntity enA = enlist[i];
             if  (enA.IsExcelVaildateOK ==  false // 上面驗證不通過,不進行此步驗證
             {
                 continue ;
             }
 
             for  ( int  j = i + 1; j < enlist.Count; j++)
             {
                 UserEntity enB = enlist[j];
                 // 判斷必填列是否全部重復
                 if  (enA.Name == enB.Name)
                 {
                     enA.IsExcelVaildateOK =  false ;
                     enB.IsExcelVaildateOK =  false ;
                     errorMsg.AppendLine( "第"  + (i + 1) +  "行與第"  + (j + 1) +  "行的必填列重復了" );
                 }
             }
         }
 
         #endregion
 
         // TODO:其他檢測
 
         #endregion
 
         // 3.TODO:對List集合持久化存儲操作。如:存儲到數據庫
         
         // 4.返回操作結果
         bool  isSuccess =  false ;
         if  (errorMsg.Length == 0)
         {
             isSuccess =  true // 若錯誤信息成都為空,表示無錯誤信息
         }
         var  rs =  new  { success = isSuccess,  msg = errorMsg.ToString(), data = enlist };
         System.Web.Script.Serialization.JavaScriptSerializer js =  new  System.Web.Script.Serialization.JavaScriptSerializer();
         context.Response.ContentType =  "text/plain" ;
         context.Response.Write(js.Serialize(rs));  // 返回Json格式的內容
     }
     catch  (Exception ex)
     {
      throw  ex;
     }
}

  

3. Excel導出

3.1 導出流程

 

3.2 NPOI操作代碼

說明:把List<T>轉換為Excel

步驟:

①創建一個工作簿(Workbook);

②在工作簿上創建一個工作表(Sheet);

③在工作表上創建第一行(row),第一行為列頭,依次寫入cellHeard的值(做為列名)。

④循環遍歷List<T>集合,每循環一遍創建一個行(row),然后根據cellHeard的鍵(屬性名稱)依次從List<T>中的實體對象取值存放到單元格內。

代碼:

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/// <summary>
/// 實體類集合導出到Excle2003
/// </summary>
/// <param name="cellHeard">單元頭的Key和Value:{ { "UserName", "姓名" }, { "Age", "年齡" } };</param>
/// <param name="enList">數據源</param>
/// <param name="sheetName">工作表名稱</param>
/// <returns>文件的下載地址</returns>
public  static  string  EntityListToExcel2003(Dictionary< string string > cellHeard, IList enList,  string  sheetName)
{
     try
     {
         string  fileName = sheetName +  "-"  + DateTime.Now.ToString( "yyyyMMddHHmmssfff" ) +  ".xls" // 文件名稱
         string  urlPath =  "UpFiles/ExcelFiles/"  + fileName;  // 文件下載的URL地址,供給前台下載
         string  filePath = HttpContext.Current.Server.MapPath( "\\"  + urlPath);  // 文件路徑
 
         // 1.檢測是否存在文件夾,若不存在就建立個文件夾
         string  directoryName = Path.GetDirectoryName(filePath);
         if  (!Directory.Exists(directoryName))
         {
             Directory.CreateDirectory(directoryName);
         }
 
         // 2.解析單元格頭部,設置單元頭的中文名稱
         HSSFWorkbook workbook =  new  HSSFWorkbook();  // 工作簿
         ISheet sheet = workbook.CreateSheet(sheetName);  // 工作表
         IRow row = sheet.CreateRow(0);
         List< string > keys = cellHeard.Keys.ToList();
         for  ( int  i = 0; i < keys.Count; i++)
         {
             row.CreateCell(i).SetCellValue(cellHeard[keys[i]]);  // 列名為Key的值
         }
 
         // 3.List對象的值賦值到Excel的單元格里
         int  rowIndex = 1;  // 從第二行開始賦值(第一行已設置為單元頭)
         foreach  ( var  en  in  enList)
         {
             IRow rowTmp = sheet.CreateRow(rowIndex);
             for  ( int  i = 0; i < keys.Count; i++)  // 根據指定的屬性名稱,獲取對象指定屬性的值
             {
                 string  cellValue =  "" // 單元格的值
                 object  properotyValue =  null // 屬性的值
                 System.Reflection.PropertyInfo properotyInfo =  null // 屬性的信息
 
                 // 3.1 若屬性頭的名稱包含'.',就表示是子類里的屬性,那么就要遍歷子類,eg:UserEn.UserName
                 if  (keys[i].IndexOf( "." ) >= 0)
                 {
                     // 3.1.1 解析子類屬性(這里只解析1層子類,多層子類未處理)
                     string [] properotyArray = keys[i].Split( new  string [] {  "."  }, StringSplitOptions.RemoveEmptyEntries);
                     string  subClassName = properotyArray[0];  // '.'前面的為子類的名稱
                     string  subClassProperotyName = properotyArray[1];  // '.'后面的為子類的屬性名稱
                     System.Reflection.PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName);  // 獲取子類的類型
                     if  (subClassInfo !=  null )
                     {
                         // 3.1.2 獲取子類的實例
                         var  subClassEn = en.GetType().GetProperty(subClassName).GetValue(en,  null );
                         // 3.1.3 根據屬性名稱獲取子類里的屬性類型
                         properotyInfo = subClassInfo.PropertyType.GetProperty(subClassProperotyName);
                         if  (properotyInfo !=  null )
                         {
                             properotyValue = properotyInfo.GetValue(subClassEn,  null );  // 獲取子類屬性的值
                         }
                     }
                 }
                 else
                 {
                     // 3.2 若不是子類的屬性,直接根據屬性名稱獲取對象對應的屬性
                     properotyInfo = en.GetType().GetProperty(keys[i]);
                     if  (properotyInfo !=  null )
                     {
                         properotyValue = properotyInfo.GetValue(en,  null );
                     }
                 }
 
                 // 3.3 屬性值經過轉換賦值給單元格值
                 if  (properotyValue !=  null )
                 {
                     cellValue = properotyValue.ToString();
                     // 3.3.1 對時間初始值賦值為空
                     if  (cellValue.Trim() ==  "0001/1/1 0:00:00"  || cellValue.Trim() ==  "0001/1/1 23:59:59" )
                     {
                         cellValue =  "" ;
                     }
                 }
 
                 // 3.4 填充到Excel的單元格里
                 rowTmp.CreateCell(i).SetCellValue(cellValue);
             }
             rowIndex++;
         }
 
         // 4.生成文件
         FileStream file =  new  FileStream(filePath, FileMode.Create);
         workbook.Write(file);
         file.Close();
 
         // 5.返回下載路徑
         return  urlPath;
     }
     catch  (Exception ex)
     {
         throw  ex;
     }
}

 

3.3 C#邏輯操作代碼

說明:對Excel轉換后的List<T>進行后續操作;如:檢測有效性、持久化存儲等等

步驟:

①獲取List<T>集合。

②調用3.2,將List<T>轉換為Excel文件。

③服務器存儲Excel文件並返回下載鏈接。

代碼:

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
public  void  ExportExcel(HttpContext context)
{
     try
     {
         // 1.獲取數據集合
         List<UserEntity> enlist =  new  List<UserEntity>() {
             new  UserEntity{Name= "劉一" ,Age=22,Gender= "Male" ,TranscriptsEn= new  TranscriptsEntity{ChineseScores=80,MathScores=90}},
             new  UserEntity{Name= "陳二" ,Age=23,Gender= "Male" ,TranscriptsEn= new  TranscriptsEntity{ChineseScores=81,MathScores=91} },
             new  UserEntity{Name= "張三" ,Age=24,Gender= "Male" ,TranscriptsEn= new  TranscriptsEntity{ChineseScores=82,MathScores=92} },
             new  UserEntity{Name= "李四" ,Age=25,Gender= "Male" ,TranscriptsEn= new  TranscriptsEntity{ChineseScores=83,MathScores=93} },
             new  UserEntity{Name= "王五" ,Age=26,Gender= "Male" ,TranscriptsEn= new  TranscriptsEntity{ChineseScores=84,MathScores=94} },
         };
 
         // 2.設置單元格抬頭
         // key:實體對象屬性名稱,可通過反射獲取值
         // value:Excel列的名稱
         Dictionary< string string > cellheader =  new  Dictionary< string string > {
             "Name" "姓名"  },
             "Age" "年齡"  },
             "GenderName" "性別"  },
             "TranscriptsEn.ChineseScores" "語文成績"  },
             "TranscriptsEn.MathScores" "數學成績"  },
         };
 
         // 3.進行Excel轉換操作,並返回轉換的文件下載鏈接
         string  urlPath = ExcelHelper.EntityListToExcel2003(cellheader, enlist,  "學生成績" );
         System.Web.Script.Serialization.JavaScriptSerializer js =  new  System.Web.Script.Serialization.JavaScriptSerializer();
         context.Response.ContentType =  "text/plain" ;
         context.Response.Write(js.Serialize(urlPath));  // 返回Json格式的內容
     }
     catch  (Exception ex)
     {
         throw  ex;
     }
}

 

3.4 代碼分析

核心代碼主要是cellheader與List<T>之間的映射關系:

 

4. 源碼下載

4.1 運行圖

 

4.2 下載地址 

百度網盤: http://pan.baidu.com/s/1o69We8M

CSDN:http://download.csdn.net/download/polk6/8974195

 

==================================系列文章=========


免責聲明!

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



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