使用npoi導入Excel - 帶合並單元格--附代碼


之前我們在使用npoi導入excel表格的時候,往往會遇見那種帶有合並單元格的數據在導入的時候出現合並為空的問題,

也就是只有第一條有數據,其余均為空白。在網上翻了半天也沒有找到合適的解決方案,最后還是想着靜下心來好好研究一番,於是...


 

我們先來看看通常我們的導入方式,如下圖,這是我們的導入模板,帶有合並單元格

下面我們來看看對應的npoi所讀到的DataTable數據

  你會發現,只有第一行有數據,其余我們合並的單元格為空值,那我們導入到數據庫必將會出錯。

於是去查看代碼,發現原來的獲取單元格值的時候並沒有去判斷單元格是否進行了合並。而正好NPOI里面正好

cell.IsMergedCell 的屬性,於是我們在檢測列的單元格是否合並,並且行數大於1的時候,我們就可以獲取值。

一旦檢測到單元格合並,並且單元格的值為空值,則讓它去取上一行的值。否則直接取單元格的值即可

 1 //讀取每列
 2 for (int j = 0; j < row.Cells.Count; j++)
 3 {
 4     ICell cell = row.GetCell(j); //一個單元格
 5     if (cell.IsMergedCell && r > 1)  //檢測列的單元格是否合並
 6     {
 7         //dr[j] = dt.Rows[r - 2][j];
 8         var cellValue = GetCellValue(cell);
 9         if (string.IsNullOrEmpty(cellValue))
10         {
11             dr[j] = dt.Rows[r - 2][j];
12         }
13         else
14         {
15             dr[j] = cellValue; //獲取單元格的值
16 
17             if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > 0)
18             {
19                 dr[j] = dr[j - 1];
20             }
21         }
22     }
23     else
24     {
25         dr[j] = GetCellValue(cell); //獲取單元格的值
26 
27         if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > 0)
28         {
29             dr[j] = dr[j - 1];
30         }
31     }
32     if (dr[j].ToString() != "")//全為空則不取
33     {
34         result = true;
35     }
36 }
37 if (result == true)
38 {
39     dt.Rows.Add(dr); //把每行追加到DataTable
40 }

 下面附上完整代碼

  1 /// <summary>
  2 /// 導入Excel 帶合並單元格  zhangyu 20200428
  3 /// </summary>
  4 /// <param name="filePath">excel文件路徑</param>
  5 /// <returns></returns>
  6 public DataTable ExcelToDataTable(string filePath)
  7 {
  8     System.Web.HttpFileCollection files = System.Web.HttpContext.Current.Request.Files;
  9     if (files.Count > 0 && files[0] != null)
 10     {
 11         if (filePath.IndexOf(".xlsx") > 0)
 12         {
 13             WorkBooks = new XSSFWorkbook(files[0].InputStream);
 14         }
 15         else
 16         {
 17             WorkBooks = new HSSFWorkbook(files[0].InputStream);
 18         }
 19     }
 20     else
 21     {
 22         FStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
 23         if (filePath.IndexOf(".xlsx") > 0)
 24         {
 25             WorkBooks = new XSSFWorkbook(FStream);
 26         }
 27         else
 28         {
 29             WorkBooks = new HSSFWorkbook(FStream);
 30         }
 31     }
 32     
 33     DataTable dt = new DataTable();
 34     IWorkbook wk = WorkBooks;
 35     //獲取后綴名
 36     string extension = filePath.Substring(filePath.LastIndexOf(".")).ToString().ToLower();
 37     //判斷是否是excel文件
 38     if (extension == ".xlsx" || extension == ".xls")
 39     {
 40         //獲取第一個sheet
 41         ISheet sheet = wk.GetSheetAt(0);
 42         //獲取第一行
 43         IRow headrow = sheet.GetRow(0);
 44         //創建列
 45         for (int i = headrow.FirstCellNum; i < headrow.Cells.Count; i++)
 46         {
 47             ICell cell = headrow.GetCell(i);
 48             dt.Columns.Add(cell.ToString());
 49         }
 50         //讀取每行,從第二行起
 51         for (int r = 1; r <= sheet.LastRowNum; r++)
 52         {
 53             bool result = false;
 54             DataRow dr = dt.NewRow();
 55             //獲取當前行
 56             IRow row = sheet.GetRow(r);
 57             //讀取每列
 58             for (int j = 0; j < row.Cells.Count; j++)
 59             {
 60                 ICell cell = row.GetCell(j); //一個單元格
 61                 if (cell.IsMergedCell && r > 1)  //檢測列的單元格是否合並
 62                 {
 63                     //dr[j] = dt.Rows[r - 2][j];
 64                     var cellValue = GetCellValue(cell);
 65                     if (string.IsNullOrEmpty(cellValue))
 66                     {
 67                         dr[j] = dt.Rows[r - 2][j];
 68                     }
 69                     else
 70                     {
 71                         dr[j] = cellValue; //獲取單元格的值
 72                         if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > 0)
 73                         {
 74                             dr[j] = dr[j - 1];
 75                         }
 76                     }
 77                 }
 78                 else
 79                 {
 80                     dr[j] = GetCellValue(cell); //獲取單元格的值
 81                     if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > 0)
 82                     {
 83                         dr[j] = dr[j - 1];
 84                     }
 85                 }
 86                 if (dr[j].ToString() != "")//全為空則不取
 87                 {
 88                     result = true;
 89                 }
 90             }
 91             if (result == true)
 92             {
 93                 dt.Rows.Add(dr); //把每行追加到DataTable
 94             }
 95         }
 96     }
 97     return dt;
 98 }
 99 /// <summary>
100 /// 對單元格進行判斷取值
101 /// </summary>
102 /// <param name="cell"></param>
103 /// <returns></returns>
104 private static string GetCellValue(ICell cell)
105 {
106     if (cell == null)
107         return string.Empty;
108     switch (cell.CellType)
109     {
110         case CellType.Blank: //空數據類型 這里類型注意一下,不同版本NPOI大小寫可能不一樣,有的版本是Blank(首字母大寫)
111             return string.Empty;
112         case CellType.Boolean: //bool類型
113             return cell.BooleanCellValue.ToString();
114         case CellType.Error:
115             return cell.ErrorCellValue.ToString();
116         case CellType.Numeric: //數字類型
117             if (HSSFDateUtil.IsCellDateFormatted(cell))//日期類型
118             {
119                 return cell.DateCellValue.ToString();
120             }
121             else //其它數字
122             {
123                 return cell.NumericCellValue.ToString();
124             }
125         case CellType.Unknown: //無法識別類型
126         default: //默認類型
127             return cell.ToString();//
128         case CellType.String: //string 類型
129             {
130                 if (cell.IsMergedCell){}
131                 return cell.StringCellValue;
132             }
133 
134         case CellType.Formula: //帶公式類型
135             try
136             {
137                 HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(cell.Sheet.Workbook);
138                 e.EvaluateInCell(cell);
139                 return cell.ToString();
140             }
141             catch
142             {
143                 return cell.NumericCellValue.ToString();
144             }
145     }
146 }

 


免責聲明!

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



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