之前我们在使用npoi导入excel表格的时候,往往会遇见那种带有合并单元格的数据在导入的时候出现合并为空的问题,

也就是只有第一条有数据,其余均为空白。在网上翻了半天也没有找到合适的解决方案,最后还是想着静下心来好好研究一番,于是...


我们先来看看通常我们的导入方式,如下图,这是我们的导入模板,带有合并单元格

下面我们来看看对应的npoi所读到的DataTable数据

你会发现,只有第一行有数据,其余我们合并的单元格为空值,那我们导入到数据库必将会出错。

于是去查看代码,发现原来的获取单元格值的时候并没有去判断单元格是否进行了合并。而正好NPOI里面正好

cell.IsMergedCell 的属性,于是我们在检测列的单元格是否合并,并且行数大于1的时候,我们就可以获取值。

一旦检测到单元格合并,并且单元格的值为空值,则让它去取上一行的值。否则直接取单元格的值即可

 //读取每列
for (int j = ; j < row.Cells.Count; j++)
{
ICell cell = row.GetCell(j); //一个单元格
if (cell.IsMergedCell && r > ) //检测列的单元格是否合并
{
//dr[j] = dt.Rows[r - 2][j];
var cellValue = GetCellValue(cell);
if (string.IsNullOrEmpty(cellValue))
{
dr[j] = dt.Rows[r - ][j];
}
else
{
dr[j] = cellValue; //获取单元格的值 if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > )
{
dr[j] = dr[j - ];
}
}
}
else
{
dr[j] = GetCellValue(cell); //获取单元格的值 if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > )
{
dr[j] = dr[j - ];
}
}
if (dr[j].ToString() != "")//全为空则不取
{
result = true;
}
}
if (result == true)
{
dt.Rows.Add(dr); //把每行追加到DataTable
}

下面附上完整代码

 /// <summary>
/// 导入Excel 带合并单元格 zhangyu 20200428
/// </summary>
/// <param name="filePath">excel文件路径</param>
/// <returns></returns>
public DataTable ExcelToDataTable(string filePath)
{
System.Web.HttpFileCollection files = System.Web.HttpContext.Current.Request.Files;
if (files.Count > && files[] != null)
{
if (filePath.IndexOf(".xlsx") > )
{
WorkBooks = new XSSFWorkbook(files[].InputStream);
}
else
{
WorkBooks = new HSSFWorkbook(files[].InputStream);
}
}
else
{
FStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
if (filePath.IndexOf(".xlsx") > )
{
WorkBooks = new XSSFWorkbook(FStream);
}
else
{
WorkBooks = new HSSFWorkbook(FStream);
}
} DataTable dt = new DataTable();
IWorkbook wk = WorkBooks;
//获取后缀名
string extension = filePath.Substring(filePath.LastIndexOf(".")).ToString().ToLower();
//判断是否是excel文件
if (extension == ".xlsx" || extension == ".xls")
{
//获取第一个sheet
ISheet sheet = wk.GetSheetAt();
//获取第一行
IRow headrow = sheet.GetRow();
//创建列
for (int i = headrow.FirstCellNum; i < headrow.Cells.Count; i++)
{
ICell cell = headrow.GetCell(i);
dt.Columns.Add(cell.ToString());
}
//读取每行,从第二行起
for (int r = ; r <= sheet.LastRowNum; r++)
{
bool result = false;
DataRow dr = dt.NewRow();
//获取当前行
IRow row = sheet.GetRow(r);
//读取每列
for (int j = ; j < row.Cells.Count; j++)
{
ICell cell = row.GetCell(j); //一个单元格
if (cell.IsMergedCell && r > ) //检测列的单元格是否合并
{
//dr[j] = dt.Rows[r - 2][j];
var cellValue = GetCellValue(cell);
if (string.IsNullOrEmpty(cellValue))
{
dr[j] = dt.Rows[r - ][j];
}
else
{
dr[j] = cellValue; //获取单元格的值
if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > )
{
dr[j] = dr[j - ];
}
}
}
else
{
dr[j] = GetCellValue(cell); //获取单元格的值
if (string.IsNullOrWhiteSpace(dr[j].ToString()) && j > )
{
dr[j] = dr[j - ];
}
}
if (dr[j].ToString() != "")//全为空则不取
{
result = true;
}
}
if (result == true)
{
dt.Rows.Add(dr); //把每行追加到DataTable
}
}
}
return dt;
}
/// <summary>
/// 对单元格进行判断取值
/// </summary>
/// <param name="cell"></param>
/// <returns></returns>
private static string GetCellValue(ICell cell)
{
if (cell == null)
return string.Empty;
switch (cell.CellType)
{
case CellType.Blank: //空数据类型 这里类型注意一下,不同版本NPOI大小写可能不一样,有的版本是Blank(首字母大写)
return string.Empty;
case CellType.Boolean: //bool类型
return cell.BooleanCellValue.ToString();
case CellType.Error:
return cell.ErrorCellValue.ToString();
case CellType.Numeric: //数字类型
if (HSSFDateUtil.IsCellDateFormatted(cell))//日期类型
{
return cell.DateCellValue.ToString();
}
else //其它数字
{
return cell.NumericCellValue.ToString();
}
case CellType.Unknown: //无法识别类型
default: //默认类型
return cell.ToString();//
case CellType.String: //string 类型
{
if (cell.IsMergedCell){}
return cell.StringCellValue;
} case CellType.Formula: //带公式类型
try
{
HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(cell.Sheet.Workbook);
e.EvaluateInCell(cell);
return cell.ToString();
}
catch
{
return cell.NumericCellValue.ToString();
}
}
}

使用npoi导入Excel - 带合并单元格--附代码的更多相关文章

  1. 用NPOI创建Excel、合并单元格、设置单元格样式、边框的方法

    本篇文章小编为大家介绍,用NPOI创建Excel.合并单元格.设置单元格样式.边框的方法.需要的朋友参考下 今天在做项目中,遇到使用代码生成具有一定样式的Excel,找了很多资料,最后终于解决了,Ex ...

  2. 导出excel带合并单元格方法的Demo

    package com.test.util; import java.io.FileNotFoundException; import java.io.FileOutputStream; import ...

  3. WPF 导出Excel(合并单元格)

    WPF 导出Excel(合并单元格) DataTable 导出Excel(导出想要的列,不想要的去掉) ,B1,B2,B3,B4,B5} MisroSoft.Office.Interop.Excel. ...

  4. .net读取Excel转datatable、.net读取的Excel存在合并单元格并且转成datatable

    项目中经常会遇到Excel导入数据,Excel的模板会可能是存在合并单元格的,模板如下图所示 读取时需要填充合并单元格的值,转成datatable单元格值时,填充合并单元格的值,如下图所示: 合并单元 ...

  5. POI导出复杂Excel,合并单元格(2)

    /** * 导出excel (HSSFWorkbook) */ @GetMapping("/testExport") public void testExport1(HttpSer ...

  6. POI导出复杂Excel,合并单元格(1)

    /** * 导出复杂excel 合并单元格 (HSSFWorkbook) */ @GetMapping("/testHSSFWorkbook.do") public void te ...

  7. poi excel设置合并单元格边框格式

    版本3.17 //设置合并单元格的边框 public static void setBorderForMergeCell(BorderStyle style,int color, CellRangeA ...

  8. 转:jxl导出excel(合并单元格)

    Demo 代码如下: import java.io.*; import jxl.*; import jxl.format.UnderlineStyle; import jxl.write.*; pub ...

  9. NPOI读取Excel日期类型单元格返回一串数字问题

    public string getCellStringNEW(int row, int column) { try { ICell cell = xlSheet.GetRow(row).Cells[c ...

随机推荐

  1. Soul Android app 悬浮view以及帖子中view的联动刷新逆向分析

    Soul app是我司的竞品,对它的语音音乐播放同步联动的逻辑很感兴趣,于是就开启了一波逆向分析. 下面看代码,以及技术分析,直接步入正轨,哈哈. 我们根据https://github.com/xin ...

  2. 从"UDF不应有状态" 切入来剖析Flink SQL代码生成

    从"UDF不应有状态" 切入来剖析Flink SQL代码生成 目录 从"UDF不应有状态" 切入来剖析Flink SQL代码生成 0x00 摘要 0x01 概述 ...

  3. 团队题目——TD课程通

    一.团队介绍 团队名称:精神小伙成双队 团队成员:冯静妃(博客地址:https://www.cnblogs.com/fengjingfei/) 李佳伟(博客地址:https://www.cnblogs ...

  4. window servet 2012 r2 配置php服务器环境

    绑定:https://jingyan.baidu.com/article/0bc808fc2c6a851bd485b92a.html 配置环境:http://www.jb51.net/article/ ...

  5. Debugging Under Unix: gdb Tutorial (https://www.cs.cmu.edu/~gilpin/tutorial/)

    //注释掉 #include <iostream.h> //替换为 #include <iostream> using namespace std; Contents Intr ...

  6. [Inno Setup] Do not show application version in “Program and Features” control panel

    Set AppVersion empty. But, then you have to set the AppVerName. Depending on your needs either set i ...

  7. Copy ArrayList的四种方式

    目录 简介 使用构造函数 使用addAll方法 使用Collections.copy 使用stream 总结 Copy ArrayList的四种方式 简介 ArrayList是我们经常会用到的集合类, ...

  8. Scala教程之:scala的参数

    文章目录 默认参数值 命名参数 scala的参数有两大特点: 默认参数值 命名参数 默认参数值 在Scala中,可以给参数提供默认值,这样在调用的时候可以忽略这些具有默认值的参数. def log(m ...

  9. Scala教程之:静态类型

    文章目录 泛类型 型变 协变 逆变 不变 类型上界 类型下界 内部类 抽象类型 复合类型 自类型 隐式参数 隐式转换 多态方法 类型推断 Scala是静态类型的,它拥有一个强大的类型系统,静态地强制以 ...

  10. NFS共享设置

    一.安装所需要的软件环境[root@fengling ~]# yum -y install rpcbind nfs-utils二.创建共享目录mkdir /web三.启动服务[root@fenglin ...