使用npoi导入Excel 支持纵向合并单元格和多行标题的情况

/// <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);
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值