使用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 }

 

### 回答1: WPF是一种用于开发桌面应用程序的技术,而NPOI是一个用于处理Excel文件的开源库。通过结合使用WPF和NPOI,我们可以在WPF应用程序中实现Excel文件的导入和导出功能。 要使用NPOI导入Excel文件,首先需要引入NPOI库。我们可以通过NuGet包管理器将NPOI库添加到我们的WPF项目中。然后,我们可以使用NPOI的API来读取和解析Excel文件。我们需要创建一个Workbook对象,并选择要读取的特定Sheet,然后使用循环遍历每一行,并读取每个单元格的值。 在WPF中,我们可以创建一个界面并添加一个按钮,用于触发Excel文件导入功能。当用户点击按钮时,我们将使用NPOI库打开文件选择对话框,允许用户选择要导入Excel文件。一旦我们获取了用户选择的文件路径,我们可以使用NPOI的API来读取Excel文件,然后将数据绑定到WPF应用程序中的相应控件上。 要使用NPOI导出Excel文件,在WPF中,我们可以将数据绑定到DataGrid或ListView等控件上。当用户点击导出按钮时,我们可以使用NPOI的API来创建一个Workbook对象,并选择要导出的Sheet。然后,我们可以使用循环遍历来将数据从WPF控件中导出到Excel文件的每一行。 最后,我们可以将导出的Excel文件保存到硬盘上的特定路径。使用NPOI的API,我们可以设置导出文件的格式和样式,例如设置单元格的字体、颜色、边框等。 总之,通过使用NPOI库,我们可以在WPF应用程序中实现Excel文件的导入和导出功能。这个过程涉及到引入NPOI库、读取和解析Excel文件、将数据绑定到WPF控件上、使用NPOI导出数据到Excel文件等步骤。 ### 回答2: WPF是一种用于构建Windows应用程序的开发框架,而NPOI是一个支持读取和写入Microsoft Office格式文件的库。使用NPOI库可以在WPF应用程序中实现Excel文件的导入和导出功能。 首先需要在WPF项目中引用NPOI库,可以通过NuGet包管理器或手动引用DLL文件的方式进行添加。 要导入Excel文件,我们可以使用NPOI库提供的类来读取和解析文件。首先需要创建一个ExcelWorkbook对象,然后通过获取工作表和行、单元格的方式来获取数据。可以使用循环遍历的方法将数据导入到WPF应用程序中的数据结构中,如数据表或集合。 要导出Excel文件,我们可以使用NPOI库提供的类来创建和写入Excel文件。首先需要创建一个ExcelWorkbook对象,然后创建工作表和行对象,并将数据写入到单元格中。最后,可以使用流将Excel文件保存到指定的位置。 需要注意的是,导入和导出Excel文件时需要处理一些异常情况,如文件格式错误、IO异常等,可以使用try-catch语句来捕获并处理这些异常。 总结来说,使用NPOI库可以方便地在WPF应用程序中实现Excel文件的导入和导出功能。通过引用NPOI库,并使用它提供的类和方法,我们可以读取和解析Excel文件的数据,以及创建和写入Excel文件。这使得我们可以更加灵活和高效地处理Excel文件,满足特定的需求。 ### 回答3: WPF是一种使用XAML语言和.NET框架开发桌面应用程序的技术。NPOI是一个用于操作Microsoft Office格式文件的开源库,可以在WPF应用程序中使用NPOI来实现Excel文件的导入和导出。 在使用NPOI导入Excel文件时,首先需要引入NPOI的相关命名空间,然后通过创建一个Workbook对象来加载Excel文件。可以使用Workbook的GetSheetAt方法获取具体的工作表,并通过遍历行和列的方式获取单元格的数据。再通过将数据存储到一个集合或数据表中,便可以在WPF应用程序中进行进一步的处理和展示。 在使用NPOI导出Excel文件时,首先需要创建一个Workbook对象,并在其中创建一个工作表。然后通过遍历数据集合或数据表,使用NPOI提供的方法在工作表中添加行和列,并设置相应的单元格数值。最后,使用Workbook的Write方法将数据写入到Excel文件中,并通过保存文件的方式实现导出功能。 此外,还可以根据需求设置单元格的样式、字体、颜色等属性,以及合并单元格、设置边框等操作。通过熟悉NPOI库的API文档,可以灵活地操作Excel文件,并在WPF应用程序中实现导入和导出Excel的功能。 总之,通过使用NPOI库,可以在WPF应用程序中方便地实现Excel文件的导入和导出功能,提高了应用程序的灵活性和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值