/// <summary>
/// Excel转DataTable
/// </summary>
/// <param name="filePath">excel文件路径</param>
/// <returns></returns>
public static DataTable ExcelToTable(string filePath)
{
DataTable dt = new DataTable();
using (FileStream fsRead = System.IO.File.OpenRead(filePath))
{
IWorkbook wk = null;
//获取后缀名
string extension = filePath.Substring(filePath.LastIndexOf(".")).ToString().ToLower();
//判断是否是excel文件
if (extension == ".xlsx" || extension == ".xls")
{
//判断excel的版本
if (extension == ".xlsx")
{
wk = new XSSFWorkbook(fsRead);
}
else if (extension == ".xls")
{
wk = new HSSFWorkbook(fsRead);
}
//获取第一个sheet
ISheet sheet = wk.GetSheetAt(0);
//获取第一行为标题
IRow headrow = sheet.GetRow(0);
//创建列
for (int i = headrow.FirstCellNum; i < headrow.Cells.Count; i++)
{
ICell cell = headrow.GetCell(i);
if (cell.ConvertToString() != null && cell.ConvertToString() != string.Empty)
{
dt.Columns.Add(cell.ToString());
}
else
{
dt.Columns.Add(new DataColumn("Columns" + i.ToString()));//标题没有名字的添加名字
}
}
//读取每行,从第二行起
for (int r = 1; r <= sheet.LastRowNum; r++)
{
DataRow dr = dt.NewRow();
//获取当前行
IRow row = sheet.GetRow(r);
int recordNullCount = 0;
//读取每列
for (int j = 0; j < headrow.Cells.Count; j++)
{
ICell cell = row.GetCell(j); //一个单元格
if (cell == null)
{
dr[j] = "";
continue;
}
if (cell.IsMergedCell && r > 1) //检测列的单元格是否合并
{
var cellValue = GetCellValue(cell);
if (string.IsNullOrEmpty(cellValue))
{
dr[j] = dt.Rows[r - 2][j];
}
else
{
dr[j] = cellValue; //获取单元格的值
}
}
else
{
dr[j] = GetCellValue(cell); //获取单元格的值
}
if (dr[j].ToString() == null || dr[j].ToString() == "")//全为空则不取
{
recordNullCount += 1;
}
if (dr[j].ToString() == "统计" || dr[j].ToString() == "合计")//如果是统计行就直接break掉
{
recordNullCount = dt.Columns.Count;
break;
}
}
if (recordNullCount == dt.Columns.Count)
{
break;
}
else
{
dt.Rows.Add(dr); //把每行追加到DataTable
}
}
}
}
return dt;
}
/// <summary>
/// 对单元格进行判断取值
/// </summary>
/// <param name="cell"></param>
/// <returns></returns>
private static string GetCellValue(ICell cell, CellType cType = CellType.Blank)
{
if (cell == null)
return string.Empty;
if (cType == CellType.Blank)
cType = cell.CellType;
switch (cType)
{
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: //数字类型
cell.SetCellType(CellType.Numeric);
if (HSSFDateUtil.IsCellDateFormatted(cell))//日期类型
{
if (cell.DateCellValue.ToString("yyyy") == "1899")
{
return cell.DateCellValue.ToString("HH:mm"); //如果只有具体时间无日期
}
if (cell.DateCellValue.ToString("HH:mm:ss") == "00:00:00")
{
return cell.DateCellValue.ToString("yyyy-MM-dd"); //如果只有日期无具体时间
}
else
{
return cell.DateCellValue.ToString("yyyy-MM-dd HH:mm:ss"); //如果日期和时间都是具体数值
}
}
else //其它数字
{
return cell.NumericCellValue.ToString();
}
case CellType.Unknown: //无法识别类型
default: //默认类型
return cell.ToString();//
case CellType.String: //string 类型
{
cell.SetCellType(CellType.String);
return cell.StringCellValue;
}
case CellType.Formula: //带公式类型
return GetCellValue(cell, cell.CachedFormulaResultType);
}
}
使用npoi导入Excel 支持纵向合并单元格和多行标题的情况
于 2022-04-01 14:13:37 首次发布